前言:今天写测试demo的时候发现了一个有趣的现象,比如在查找dom选择器的时候如果使用了通用选择器
querySelectorAll()返回的是NodeList对象,而使用parentNode.children返回的确是一个HTMLCollection对象,所以想记下二者之间的区别与相同点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<div id="father"> <div id="son1">son1</div> <div id="son2">son2</div> </div> <script> let father = document.getElementById('father'); let sons = document.querySelectorAll('div[id^=son]'); let divs = document.getElementsByTagName('div'); // NodeList console.log(sons); console.log(father.childNodes); // HTMLCollection console.log(father.children); console.log(divs) </script>
HTMLCollection对象
HTMLCollection 接口表示一个包含了元素(元素顺序为文档流中的顺序)的通用集合(generic collection),还提供了用来从该集合中选择元素的方法和属性。——MDN—HTMLCollection
属性:
HTMLCollection.length(只读):返回集合当中子元素的数目。
方法:
-
HTMLCollection.item(i):根据传入的索引值,返回具体的节点。如果节点不存在,则返回null。 -
HTMLCollection.namedItem(str):根据穿入的字符串,作为关键字,先根据关键字先查找对应id的元素,如果元素不存在则根据字符串所表示的name属性来匹配。测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<div id="father"> <div id="son1">son1</div> <div id="son2" name="son1">son2</div> <div name="son3">son3</div> </div> <script> let divs = document.getElementsByTagName('div'); // 获取HTMLCollection的长度 console.log(divs.length); // true console.log(divs instanceof HTMLCollection); // divs[2].innerText = 'nmsl' console.log(divs.item(0)); let degreeElement = divs.namedItem('son3') </script>
注意:
HTMLCollection对象,虽然可以通过数组下标访问元素,但是不可以使用数组对象的方法。
NodeList对象
NodeList 对象是一个节点的集合,是由 Node.childNodes 和 document.querySelectorAll 返回的.——MDN—NodeList
属性:
NodeList.length:NodeList 中包含的节点个数。
方法:
NodeList.item():根据传入的索引值,返回具体的节点。如果节点不存在,则返回null。与nodeList[i]等价,如果此时越界返回undefined。NodeList.forEach():用于遍历NodeList中的所有成员。其使用和数组对象的forEach方法完全一样。NodeList.keys()/values()/entries():keys()返回键名的遍历器,values()返回键值的遍历器,entries()返回的遍历器同时包含键名和键值的信息。
测试用例:
|
|
测试结果如图所示:

在大部分时候NodeList是一个静态集合,可以将其理解做给网页上符合条件的DOM节点拍下了一张快照,也就意味着随后对文档对象模型的任何改动都不会影响集合的内容。比如说比如 document.querySelectorAll 就会返回一个静态 NodeList。
可以看下下面这个案例理解一下,代码:
|
|
在一些情况下,NodeList 是一个 实时集合 ,也就是说,如果文档中的节点树发生变化,NodeList 也会随之变化,比如,Node.childNodes 就是是实时的:
|
|
HTMLCollection 与 NodeList 的相同点与不同点
不同点
HTMLCollection是个元素的集合,不包含文本、注释节点等。NodeList是节点的集合,可以包含文本、注释节点。- 大部分时候
NodeList是一个静态的结合,不受DOM树的影响,相当于DOM树的快照,节点数量和类型的快照,就是对节点增删,NodeList感觉不到,但是对节点内部内容修改,是可以感觉到的,比如修改innerHTML。 HTMLCollection是动态绑定的,是一个的动态集合,DOM 树发生变化,HTMLCollection也会随之变化,节点的增删是敏感的。HTMLCollection元素可以通过name,id(nameItem方法) 或 index(item方法) 索引来获取。NodeList只能通过index(item方法) 索引来获取。- 二者都无法使用数组的方法,除非转为一个数组。
- :
NodeList的原型链:myNodeList --> NodeList.prototype --> Object.prototype --> null - :
HTMLCollection的原型链:myHTMLCollection --> HTMLCollection.prototype --> Object.prototype --> null
- :
相同点
- 都是伪数组结构的数据,都有
length属性 - 都拥有
item()方法获取,集合内对应索引号的元素