手拉手一起学JavaScript——HTMLCollection和NodeList

61 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

抛砖引玉

  • 假设有一个节点nodeclassNamecontianerdocument.querySelectorAll('.container')document.getElementsByClassName('container')是否相同?
  • 假设有一个节点node,使用node.childrennode.childNodes时,返回值是否相同?

实例分析

demo

使用浏览器打开当前页面,可以看到如下结果:

结果

实例结果

  • 可以看出在使用querySelectorAll的时候,返回类型是NodeList,在使用getElementsByClassName的时候返回类型是HTMLCollection,所以可以对第一个问题进行解答,document.querySelectorAll('.container')document.getElementsByClassName('container')的返回类型不同。但是看上去返回的内容是一样的,querySelector方法会返回什么类型呢?经过对返回内容的比较,可以得出返回的内容和和querySelector返回的内容一样。
  • 在对某个节点使用node.children时,返回类型是HTMLCollection,在使用node.childNodes时返回类型是NodeList,除了返回类型不同之外,返回的内容也不一样,node.childNodes返回的节点更多。

HTMLCollectionNodeList

使用

  • 对实例中返回的HTMLCollectionNodeList数据使用Array.isArray判断是否是数组时,返回值都是false,即不是数组,但是有length,可以使用for...of遍历,NodeList可以使用forEach遍历,HTMLCollection只能用for循环遍历,和arguments一样,这些数据类型是类数组,在处理类数组的时候,可以使用Array.from()把类数组转为普通数组,就可以使用数组相关的操作,比如mapfilterreduce等。

内部构成

  • NodeList:节点集合,节点是NodeNode是一个接口,DOM API对象都是从Node继承而来,比如元素ElementNode的种类比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继承自ElementSVGElement也继承自Element,而Element继承自NodeNodeList是由Node组成的。
  • querySelector是查找元素的,querySelectorAll是查找节点的,getElement-开头的方法是查找元素的,children是获取的子元素,childNodes获取的是节点。
  • HTMLCollection是动态的实时的,NodeListdocument.querySelectorAll()的时候是静态的,其他的大部分时候也是动态的。
  • 在对DOM进行操作的时候,分清楚什么是元素,什么是节点,要处理的是元素还是节点,是要动态计算还是维持静态数组等问题,DOM处理起来会更加得心应手。
  • 今天也是有收获的一天。