NodeList
对象是一个节点的集合,是由Node.childNodes
and the querySelectorAll返回的.
length
NodeList对象
中包含的节点个数.
item ( idx )
返回NodeList对象中指定索引的节点,如果索引越界,则返回null
.也可以简写为nodeList[idx].
大多数情况下,NodeList
对象都是个live集合.意思是说,如果文档中的节点树发生变化,则已经存在的NodeList对象也可能会变化.
var links = document.getElementsByTagName('a');// 假如现在links.length === 2.document.body.appendChild( links[0].cloneNode(true) ); // 文档中又添加了一个a.// 则links这个NodeList对象也会改变.// links.length === 3
但如果该NodeList
对象是由document.querySelectorAll
(或者Element.querySelectorAll
)方法返回的, 则它是非live的(就算把页面内的所有节点清空,links.length
还等于2).
NodeList
对象在某些方面和数组非常相似,看上去可以直接使用从Array.prototype
上继承的方法.然而,这是不可以的.
JavaScript的继承机制是基于原型的.数组元素之所以有一些数组方法( 比如forEach
和map
),是因为它的原型链上有这些方法,如下:
myArray --> Array.prototype --> Object.prototype --> null (想要获取一个对象的原型链,可以连续的调用Object.getPrototypeOf,直到原型链尽头).
forEach
, map
这些方式其实是 Array.prototype
这个对象的方法.
和数组不一样, NodeList
的原型链是这样的:
myNodeList --> NodeList.prototype --> Object.prototype --> null
NodeList.prototype
只有一个item
方法, 没有Array.prototype
上的那些方法, 所以NodeList
对象用不了它们.
一个解决办法就是把Array.prototype
上的方法添加到NodeList.prototype
上. 可是, 要注意扩展DOM对象的原型是非常危险的,尤其是在旧版本的Internet Explorer(6,7,8)中
for(prop in Array.prototype){ if(Array.prototype.hasOwnProperty(prop) && typeof(Array.prototype[prop]) === 'function') NodeList[prop] = Array.prototype[prop];}var links = document.getElementsByTagName('a');links.forEach(function(link){ // 在一些浏览器中会抛异常 link.style.color = '#0F0';});
不扩展DOM对象原型的解决办法:
var forEach = Array.prototype.forEach;var links = document.getElementsByTagName('a');forEach.call(links, function(link){ // 未发现有浏览器不支持 link.style.color = '#0F0';});
遍历一个NodeList
对象中的所有的节点可以使用如下代码:
for (var i = 0; i < myNodeList.length; ++i) { var item = myNodeList[i]; // 可以简写为myNodeList[i].}
不要尝试使用 for...in
或者 for each...in
来遍历一个NodeList
对象中的元素, 因为NodeList
对象中的length和item属性也会被遍历出来,这可能会导致你的脚本运行出错,如果你把上述两个属性也看成DOM对象的话.