前言:今天写测试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()
方法获取,集合内对应索引号的元素