从 Node 和 Element 到 HTMLCollection 和 NodeList(浅析)

1,440 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第11天,点击查看活动详情

HTMLCollection和NodeList有什么区别?

这个问题考察的是 Html 基础知识和 js 的基础知识,这两个类型使我们经常见的,但是可能有的同学会比较混乱,有的时候出现这个有的时候又出现哪个。总之这两个类型都是包含了很多元素的集合,但是为什么会有这两个类型?搞不清楚。。。

在我们要纠结这个问题的之前,我们要先了解 Node 和 Element 的区别。

Node 和 Element 的区别

我们经常使用document.getElementById去获取DOM中的元素,也会使用childNodes来获取子节点。那么Element和Node的区别是什么? 在我们纠结这个问题之前,我们先看一张图: image.png

我们知道 js 中的 DOM 操作 有 NodeElement,而图中那么NodeElement 的关系是父子节点的关系,简单的说就是Node是一个基类,而Element继承于它

Element 继承于 Node,具有Node的方法,同时又拓展了很多自己的特有方法。 从而也可以得出一个结论:

Element 一定是 Node,但 Node 不一定是 Element

小结

  • Dom 是一棵树,所有节点都是 Node
  • NodeElement 的基类
  • Element 是其他 HTML 元素的基类,如 HTMLDovElement
  • Element 一定是 Node,但 Node 不一定是 Element

HTMLCollection 和 NodeList 的区别

其实这里的区别我们可以从官方给的 DOM Standard中看个大概了

4.2.10.1. Interface NodeList
interface NodeList {
  getter Node? item(unsigned long index);
  readonly attribute unsigned long length;
  iterable<Node>;
};
4.2.10.2. Interface HTMLCollection
interface HTMLCollection {
  readonly attribute unsigned long length;
  getter Element? item(unsigned long index);
  getter Element? namedItem(DOMString name);
};

看到这里我们抛出一个结论:

  • HTMLCollectionElement 的集合
  • NodeListNode 的集合 再结合上面总结的的 Node 和 Element 的区别,是不是更有心得了?

HTMLCollection 和 NodeList是一个类数组而不是数组 为什么 NodeList 不是数组?

来个拓展:children与childNodes的区别?

children

我们通过children获取元素的子元素,来了解一下children的父类:

html:

...
<div id="app">
  <b>node</b> 
  vs 
  <em>element</em>
  <!--注释-->
</div>
...

js:

const div1 = document.getElementById('app')
console.log(div1.children)

image.png 这里虽然 children 输出了 bem 标签,但是却没有 vs(文本) 和 <!--注释--> 两个节点

这里我们可以得出一个结论: childrenHTMLCollection的集合

console.log('HTMLCollection', div1.children instanceof HTMLCollection)
console.log('NodeList', div1.children instanceof NodeList)

image.png

childNodes

我们同样通过childNodes获取元素的子元素,来了解一下childNodes的父类:

html:

...
<div id="app"><b>node</b>vs <em>element</em><!--注释--></div>
...

js:

const div1 = document.getElementById('app')
console.log(div1.childNodes)

image.png 这里vs(文本) 和 <!--注释--> 两个节点也都完整的输出了

这里我们可以得出一个结论: childNodesNodeList的集合

console.log('HTMLCollection', div1.children instanceof HTMLCollection)
console.log('NodeList', div1.children instanceof NodeList)

image.png

小结:

W3C中的解释是:

在 HTML DOM (文档对象模型)中,每个部分都是节点:

  • 文档本身是文档节点
  • 所有 HTML 元素是元素节点
  • 所有 HTML 属性是属性节点
  • HTML 元素内的文本是文本节点 (包括回车符也是属于文本节点)
  • 注释是注释节点

划重点

  • 获取 Node 和 Element 的返回结果可能不一样
  • 如 elem.chidNodes 和 elem.children 不一样
  • 还是这张图 image.png

相关推荐

【1】聊聊Node(节点)和Element(元素)有什么区别
【2】* 原生DOM探究 -- NodeList v.s. HTMLCollection
【3】* 为什么 NodeList 不是数组?