mozilla
您的搜索结果

    NodeList

    NodeList对象是一个节点的集合,是由Node.childNodesdocument.querySelectorAll 返回的.

    属性

    length

    NodeList对象中包含的节点个数.

    方法

    item ( idx )
    返回NodeList对象中指定索引的节点,如果索引越界,则返回null.等价的写法是nodeList[idx], 不过这种情况下越界访问将返回undefined.

    描述

    一个"有时实时"的集合

    大多数情况下,NodeList对象都是个实时集合.意思是说,如果文档中的节点树发生变化,则已经存在的NodeList对象也可能会变化. 例如,Node.childNodes 是实时的:

    var parent = document.getElementById('parent');
    var child_nodes = parent.childNodes;
    console.log(child_nodes.length); // 如果假设结果是“2”
    parent.appendChild(document.createElement('div'));
    console.log(child_nodes.length); // 此时的输出是“3”

    在另一些情况下,NodeList 是一个静态集合,也就意味着随后对文档对象模型的任何改动都不会影响集合的内容。document.querySelectorAll 返回一个静态的 NodeList

    特别是当你选择如何遍历 NodeList 中所有项,或缓存列表长度的时候,最好牢记这种区分。

    什么NodeList不是数组?

    NodeList对象在某些方面和数组非常相似,看上去可以直接使用从Array.prototype上继承的方法.然而,这是不可以的.

    JavaScript的继承机制是基于原型的.数组元素之所以有一些数组方法( 比如forEachmap),是因为它的原型链上有这些方法,如下:

    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)中

    var arrayMethods = Object.getOwnPropertyNames( Array.prototype );
    
    arrayMethods.forEach( attachArrayMethodsToNodeList );
    
    function attachArrayMethodsToNodeList(methodName)
    {
      if(methodName !== "length") {
        NodeList.prototype[methodName] = Array.prototype[methodName];
      }
    };
     
    var divs = document.getElementsByTagName( 'div' );
    var firstDiv = divs[ 0 ];
    
    firstDiv.childNodes.forEach(function( divChild ){
      divChild.parentNode.style.color = '#0F0';
    });

    不扩展DOM对象原型的解决办法:

    var forEach = Array.prototype.forEach;
    
    var divs = document.getElementsByTagName( 'div' );
    var firstDiv = divs[ 0 ];
    
    forEach.call(firstDiv.childNodes, function( divChild ){
      divChild.parentNode.style.color = '#0F0';
    });

    请注意,在上面的代码中,将某个宿主对象 (如 NodeList) 作为 this 传递给原生方法 (如 forEach) 不能保证在所有浏览器中工作,已知在一些浏览器中会失败。

    例子

    遍历一个NodeList对象中的所有的节点可以使用如下代码:

    for (var i = 0; i < myNodeList.length; ++i) {
      var item = myNodeList[i];  // 调用 myNodeList.item(i) 是没有必要的
    }
    

    不要尝试使用 for...in 或者 for each...in 来遍历一个NodeList 对象中的元素,因为NodeList对象中的lengthitem属性也会被遍历出来,这可能会导致你的脚本运行出错,如果你把上述两个属性也看成 elemnt 对象的话。此外,for...in 不能保证访问这些属性的顺序。

    for...of 循环将会正确的遍历 NodeList 对象,浏览器中支持的 for...of (比如 Firefox 13 及以后版本):

    var list = document.querySelectorAll( 'input[type=checkbox]' );
    for (var item of list) {
      item.checked = true;
    }

    将NodeList转换为Array

    有时候用类似数组的方法来处理 NodeList 里的内容会更加方便。这里有一种技术为了将 NodeList 对象转换为数组:

    var div_list = document.querySelectorAll('div'); // 返回 NodeList
    var div_array = Array.prototype.slice.call(div_list); // 将 NodeList 转换为数组

    规范

    文档标签和贡献者

    标签: 
    此页面的贡献者有: ziyunfei, fishenal, Hawkeyes_Wind, teoli, jaka
    最后编辑者: Hawkeyes_Wind,