如何将元素的 NamedNodeMap 克隆到空对象?
How do you clone an element's NamedNodeMap to an empty object?
我有一个 javaScript 对象数组,其中对象称为 text,其中每个对象元素包含有关 HTML 元素的信息使用 Chrome 浏览器的检查源监视区域如下所示:
text:
attributes: NamedNodeMap
0: baseURI: "file:.../awesomplete_textarea.html"
childNodes: NodeList []
firstChild: null
isConnected: false
lastChild: null
localName: "label"
name: "label"
namespaceURI: null
nextSibling: null
nodeName: "label"
nodeType: 2
nodeValue: "Alternative Rock"
ownerDocument: document
ownerElement: li
parentElement: null
parentNode: null
prefix: null
previousSibling: null
specified: true
textContent: "Alternative Rock"
value: "Alternative Rock"
__proto__: Attr }
length: 1
label: { same content as 0, above }
__proto__: NamedNodeMap }
label: "Alternative Rock"
tagName: "LI"
value: "Alternative Rock (Alternative)"
length: 16
__proto__: String
注意:虽然 attributes 成员 text 对象(以上)仅包含label 属性的信息,它还可以包含其他属性项,例如样式 and/or class,它们是从一组 <li>
标记在我的网页中,在这种情况下,text 对象和 attributes[=59 中会有其他条目=] 那些属性项的成员。
收集信息 <li>
标签后,使用如下所示的 copyAttributes 函数将标签的属性复制到 text 对象中,效果很好。
不过,以后尝试使用相同的copyAttributes函数复制text.attributes[=59时=] 到 attr 变量然后创建一个新的 HTML 元素,我得到这个错误:
mycode.js:98 Uncaught TypeError: to.setNamedItem is not a function
at copyAttributes (mycode.js:98)
at Function._.ITEM (mycode.js:940)
at _.item (mycode_textarea.html:625)
at mycode.js:826
at Array.forEach (<anonymous>)
at _.evaluate (mycode.js:825)
下面的代码显示了这个调用是如何进行的,以及我试图将信息复制到 attr 对象变量中。
function copyAttributes( from, to ) {
var attr;
for( const [ key, value ] of Object.entries( from ) ) {
if( !isNaN( key ) ) { // Only add the named attributes ...
let name = from[ key ].name;; // get the attribute's name
if( to[ name ] === undefined ) {
attr = document.createAttribute( name ); // Create the attribute.
attr.value = value.value; // Assign its value.
to.setNamedItem( attr ); // Add it to to
}
}
}
}
var tagName = 'li';
var attribute = {};
// Copy the text.attributes from the text object to attributes.
copyAttributes( text.attributes, attributes );
// Add the information in the {...} object to the attributes object ...
Object.assign( attributes,
attributes,
{ innerHTML: label, // Add these to those just copied.
'role': 'option',
'id': 'list_' + this.count +
'_item_' + item_id,
'value': value } );
// Create the new `<li>` with the original tag's attributes and those added, above.
$.create( tagName, attributes );
问题好像是copyAttributes函数的to
参数不是NamedNodeMap类型,所以不支持setNamedItem
方法。
如何创建一个空的 attributes 这种类型的变量?
或者是否有 better/easier 方法用 test[= 填充 attributes 变量57=].属性信息?
谢谢。
这是一个 codepen 下拉组合框的工作版本,它正确地创建了 li 标签元素并将所需的属性复制到其中。
此创建函数来自 Awesomplete 插件,但已修改为不将焦点设置在新创建的元素上。
$.create = function( tag, o ) {
var element = document.createElement( tag );
for( var i in o ) {
var val = o[ i ];
if( i === 'inside' ) {
$( val ).appendChild( element );
}
else if( i === 'around' ) {
var ref = $( val );
ref.parentNode.insertBefore( element, ref );
element.appendChild( ref );
if( ref.getAttribute( 'autofocus' ) != null ) {
ref.focus();
}
}
else if( i in element ) {
element[ i ] = val;
}
else {
element.setAttribute( i, val );
}
}
return element;
};
这是我修改后的代码,调用上面的创建函数并分配属性。
if( tagName === 'LI' ) {
matched = ( inputValue = ( ', ' +
me.input.value.trim().toLowerCase() +
',' ) ) // Normalize input.value so that the first item can be found.
.includes( ', ' + value.toLowerCase() + ',' ) || // Find the normalized value in the normalized input.value ...
inputValue.includes( ', ' +
label.toLowerCase() + ',' ); // Find the normalized label in the normalized input.value ...
Object.assign( attributes,
attributes,
{ 'role': 'option',
'id': 'awesomplete_list_' +
this.count +
'_item_' + item_id,
'value': value, // Give every option ( li ) a value attribute.
'aria-selected': matched.toString() } ); // If a match was found then set aria-selected to 'true'
// else set area-selected to 'false'.
}
else {
matched = false;
}
newTag = $.create( tagName );
newTag.innerHTML = label;
if( text.attributes.length ) {
// Now copy the attributes ...
copyAttributes( text.attributes, newTag.attributes );
// Add the rest of the attributes ...
copyAttributes( attributes, newTag.attributes, true );
}
return newTag;
我有一个 javaScript 对象数组,其中对象称为 text,其中每个对象元素包含有关 HTML 元素的信息使用 Chrome 浏览器的检查源监视区域如下所示:
text:
attributes: NamedNodeMap
0: baseURI: "file:.../awesomplete_textarea.html"
childNodes: NodeList []
firstChild: null
isConnected: false
lastChild: null
localName: "label"
name: "label"
namespaceURI: null
nextSibling: null
nodeName: "label"
nodeType: 2
nodeValue: "Alternative Rock"
ownerDocument: document
ownerElement: li
parentElement: null
parentNode: null
prefix: null
previousSibling: null
specified: true
textContent: "Alternative Rock"
value: "Alternative Rock"
__proto__: Attr }
length: 1
label: { same content as 0, above }
__proto__: NamedNodeMap }
label: "Alternative Rock"
tagName: "LI"
value: "Alternative Rock (Alternative)"
length: 16
__proto__: String
注意:虽然 attributes 成员 text 对象(以上)仅包含label 属性的信息,它还可以包含其他属性项,例如样式 and/or class,它们是从一组 <li>
标记在我的网页中,在这种情况下,text 对象和 attributes[=59 中会有其他条目=] 那些属性项的成员。
收集信息 <li>
标签后,使用如下所示的 copyAttributes 函数将标签的属性复制到 text 对象中,效果很好。
不过,以后尝试使用相同的copyAttributes函数复制text.attributes[=59时=] 到 attr 变量然后创建一个新的 HTML 元素,我得到这个错误:
mycode.js:98 Uncaught TypeError: to.setNamedItem is not a function
at copyAttributes (mycode.js:98)
at Function._.ITEM (mycode.js:940)
at _.item (mycode_textarea.html:625)
at mycode.js:826
at Array.forEach (<anonymous>)
at _.evaluate (mycode.js:825)
下面的代码显示了这个调用是如何进行的,以及我试图将信息复制到 attr 对象变量中。
function copyAttributes( from, to ) {
var attr;
for( const [ key, value ] of Object.entries( from ) ) {
if( !isNaN( key ) ) { // Only add the named attributes ...
let name = from[ key ].name;; // get the attribute's name
if( to[ name ] === undefined ) {
attr = document.createAttribute( name ); // Create the attribute.
attr.value = value.value; // Assign its value.
to.setNamedItem( attr ); // Add it to to
}
}
}
}
var tagName = 'li';
var attribute = {};
// Copy the text.attributes from the text object to attributes.
copyAttributes( text.attributes, attributes );
// Add the information in the {...} object to the attributes object ...
Object.assign( attributes,
attributes,
{ innerHTML: label, // Add these to those just copied.
'role': 'option',
'id': 'list_' + this.count +
'_item_' + item_id,
'value': value } );
// Create the new `<li>` with the original tag's attributes and those added, above.
$.create( tagName, attributes );
问题好像是copyAttributes函数的to
参数不是NamedNodeMap类型,所以不支持setNamedItem
方法。
如何创建一个空的 attributes 这种类型的变量?
或者是否有 better/easier 方法用 test[= 填充 attributes 变量57=].属性信息?
谢谢。
这是一个 codepen 下拉组合框的工作版本,它正确地创建了 li 标签元素并将所需的属性复制到其中。
此创建函数来自 Awesomplete 插件,但已修改为不将焦点设置在新创建的元素上。
$.create = function( tag, o ) {
var element = document.createElement( tag );
for( var i in o ) {
var val = o[ i ];
if( i === 'inside' ) {
$( val ).appendChild( element );
}
else if( i === 'around' ) {
var ref = $( val );
ref.parentNode.insertBefore( element, ref );
element.appendChild( ref );
if( ref.getAttribute( 'autofocus' ) != null ) {
ref.focus();
}
}
else if( i in element ) {
element[ i ] = val;
}
else {
element.setAttribute( i, val );
}
}
return element;
};
这是我修改后的代码,调用上面的创建函数并分配属性。
if( tagName === 'LI' ) {
matched = ( inputValue = ( ', ' +
me.input.value.trim().toLowerCase() +
',' ) ) // Normalize input.value so that the first item can be found.
.includes( ', ' + value.toLowerCase() + ',' ) || // Find the normalized value in the normalized input.value ...
inputValue.includes( ', ' +
label.toLowerCase() + ',' ); // Find the normalized label in the normalized input.value ...
Object.assign( attributes,
attributes,
{ 'role': 'option',
'id': 'awesomplete_list_' +
this.count +
'_item_' + item_id,
'value': value, // Give every option ( li ) a value attribute.
'aria-selected': matched.toString() } ); // If a match was found then set aria-selected to 'true'
// else set area-selected to 'false'.
}
else {
matched = false;
}
newTag = $.create( tagName );
newTag.innerHTML = label;
if( text.attributes.length ) {
// Now copy the attributes ...
copyAttributes( text.attributes, newTag.attributes );
// Add the rest of the attributes ...
copyAttributes( attributes, newTag.attributes, true );
}
return newTag;