这是其中一个看起来如此简单,但我无法想出一个好办法。
我有一个节点,也许nodelist = document.getElementById("mydiv");
- 我需要将其规范化为节点列表。而不是一个数组:一个真实的,真正的nodeList
对象。
不 nodelist = [document.getElementById("mydiv")];
请不要图书馆。
答案 0 :(得分:6)
获取JavaScript中已引用的任何元素,给它一个我们可以使用选择器找到的属性,找到它作为列表,删除属性,返回列表。
function toNodeList(elm){
var list;
elm.setAttribute('wrapNodeList','');
list = document.querySelectorAll('[wrapNodeList]');
elm.removeAttribute('wrapNodeList');
return list;
}
从bfavaretto的答案扩展而来。
function toNodeList(elm, context){
var list, df;
context = context // context provided
|| elm.parentNode; // element's parent
if(!context && elm.ownerDocument){ // is part of a document
if(elm === elm.ownerDocument.documentElement || elm.ownerDocument.constructor.name === 'DocumentFragment'){ // is <html> or in a fragment
context = elm.ownerDocument;
}
}
if(!context){ // still no context? do David Thomas' method
df = document.createDocumentFragment();
df.appendChild(elm);
list = df.childNodes;
// df.removeChild(elm); // NodeList is live, removeChild empties it
return list;
}
// selector method
elm.setAttribute('wrapNodeList','');
list = context.querySelectorAll('[wrapNodeList]');
elm.removeAttribute('wrapNodeList');
return list;
}
我最近想到的另一种方法是
var _NodeList = (function () {
var fragment = document.createDocumentFragment();
fragment.appendChild(document.createComment('node shadows me'));
function NodeList (node) {
this[0] = node;
};
NodeList.prototype = (function (proto) {
function F() {} // Object.create shim
F.prototype = proto;
return new F();
}(fragment.childNodes));
NodeList.prototype.item = function item(i) {
return this[+i || 0];
};
return NodeList;
}());
现在
var list = new _NodeList(document.body); // note **new**
list.constructor === NodeList; // all these are true
list instanceof NodeList;
list.length === 1;
list[0] === document.body;
list.item(0) === document.body;
答案 1 :(得分:5)
如果您定位支持document.querySelectorAll
的浏览器,它将始终返回NodeList
。所以:
var nodelist = document.querySelectorAll("#mydiv");
答案 2 :(得分:4)
恢复这个因为我最近记得有关 JavaScript 的一些事情。这取决于如何检查 NodeList ,但是..
var singleNode = (function () {
// make an empty node list to inherit from
var nodelist = document.createDocumentFragment().childNodes;
// return a function to create object formed as desired
return function (node) {
return Object.create(nodelist, {
'0': {value: node, enumerable: true},
'length': {value: 1},
'item': {
"value": function (i) {
return this[+i || 0];
},
enumerable: true
}
}); // return an object pretending to be a NodeList
};
}());
现在,如果你这样做
var list = singleNode(document.body); // for example
list instanceof NodeList; // true
list.constructor === NodeList; // true
和list
将属性 length 1
和 0 作为您的节点,以及从 NodeList
如果您无法使用Object.create
,除了作为原型nodelist
的构造函数并设置this['0'] = node;
,this['length'] = 1;
并使用{{1 }}
答案 3 :(得分:3)
var nodeList = document.createDocumentFragment();
nodeList.appendChild(document.getElementById("myDiv"));
答案 4 :(得分:0)
另一种基于Reflect.construct的方法:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct
与其他情况一样,它需要修补NodeList.prototype.item才能调用此函数。
NodeList.prototype.item = function item(i) {
return this[+i || 0];
};
let nl = Reflect.construct(Array, [], NodeList);
使用节点创建它,将节点数组作为第二个参数传递。 此方法通过检查:
list instanceof NodeList; // true
list.constructor === NodeList; // true
使用它创建的数组可以使用for..of
,forEach
和其他标准方法进行迭代,您可以使用简单的nl[n] = node;
向其中添加元素。