携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
抛砖引玉
- 假设有一个节点
node
的className
是contianer
,document.querySelectorAll('.container')
和document.getElementsByClassName('container')
是否相同? - 假设有一个节点
node
,使用node.children
和node.childNodes
时,返回值是否相同?
实例分析
使用浏览器打开当前页面,可以看到如下结果:
实例结果
- 可以看出在使用
querySelectorAll
的时候,返回类型是NodeList
,在使用getElementsByClassName
的时候返回类型是HTMLCollection
,所以可以对第一个问题进行解答,document.querySelectorAll('.container')
和document.getElementsByClassName('container')
的返回类型不同。但是看上去返回的内容是一样的,querySelector
方法会返回什么类型呢?经过对返回内容的比较,可以得出返回的内容和和querySelector
返回的内容一样。 - 在对某个节点使用
node.children
时,返回类型是HTMLCollection
,在使用node.childNodes
时返回类型是NodeList
,除了返回类型不同之外,返回的内容也不一样,node.childNodes
返回的节点更多。
HTMLCollection
和NodeList
使用
- 对实例中返回的
HTMLCollection
和NodeList
数据使用Array.isArray
判断是否是数组时,返回值都是false
,即不是数组,但是有length
,可以使用for...of
遍历,NodeList
可以使用forEach
遍历,HTMLCollection
只能用for
循环遍历,和arguments
一样,这些数据类型是类数组,在处理类数组的时候,可以使用Array.from()
把类数组转为普通数组,就可以使用数组相关的操作,比如map
、filter
、reduce
等。
内部构成
NodeList
:节点集合,节点是Node
,Node
是一个接口,DOM API
对象都是从Node
继承而来,比如元素Element
,Node
的种类比Element
要多,比如#text
HTMLCollection
:元素集合,至于为什么是HTMLCollection
有历史原因,因为在DOM4
之前,实现这个接口的都是HTML
元素,现在已经是文档流的所有元素,元素是Element
,就是继承自Node
。- 再看实例中的
querySelector
方法返回的和HTMLCollection
中的第0
个和NodeList
中的第0
个元素相同,Element
继承自Node
,从而querySelector
返回的是元素Element
。
实时性
- 当
document
发生变化时,HTMLCollection
是动态变化的,而NodeList
是不一定变化的,一般情况下,当节点发生了变化,NodeList
也会跟着发生变化,但是document.querySelectorAll()
是静态的,不会变化,因此在记录节点变化的时候,需要注意这一个特殊的点。
总结
HTMLCollection
是由Element
组成的,HTMLElement
继承自Element
,SVGElement
也继承自Element
,而Element
继承自Node
,NodeList
是由Node
组成的。querySelector
是查找元素的,querySelectorAll
是查找节点的,getElement-
开头的方法是查找元素的,children
是获取的子元素,childNodes
获取的是节点。HTMLCollection
是动态的实时的,NodeList
在document.querySelectorAll()
的时候是静态的,其他的大部分时候也是动态的。- 在对
DOM
进行操作的时候,分清楚什么是元素,什么是节点,要处理的是元素还是节点,是要动态计算还是维持静态数组等问题,DOM
处理起来会更加得心应手。 - 今天也是有收获的一天。