NodeList 和 HTMLCollection

概述

旧样式集合(Old-style):NodeList 和 HTMLCollection。

集合(collection)是表示节点列表的对象。集合可以是实时或静态的。除非另有说明,集合必须是实时的(live)。

如果集合是实时的,那么该对象上的属性和方法必须对实际的底层数据操作,而不是数据的快照。

创建集合时,过滤器(filter)和根(root)将与其关联。

然后,集合表示根集于根集合的子树的视图,仅包含与给定过滤器匹配的节点。视图是线性的。在没有相反的特定要求的情况下,集合中的节点必须以树的顺序排序。

NodeList

NodeList 对象是节点的集合。它是由 Node.childNodes 和 document.querySelectorAll 所返回的。

有时,它是一个实时的集合,例如 Node.childNodes。我们来看个示例:

var parent = document.getElementById('parent');
var child_nodes = parent.childNodes;
console.log(child_nodes.length); // 我们得到了 "2"
parent.appendChild(document.createElement('div'));
console.log(child_nodes.length); // 此时输出 "3"

这很好的证明了它是一个动态的节点。

而 document.querySelectorAll 所返回的节点却是静态的,也就是一个快照。也就意味着随后对 DOM 的任何改动都不会影响集合的内容。

NodeList 接口表示由数字(从零开始)索引的节点的有序集合。因此它拥有 length 属性。

它就是一个类数组对象。

比如我们现在创建一个 ul 列表:

  • You
  • And
  • Me

接着我们使用 NodeList 来返回它的子节点:

let ul = document.getElementById('ul');
console.log(ul.childNodes);

返回的结果如下所示:

NodeList 和 HTMLCollection_第1张图片

我们可以从控制台的结果看出,它确实返回了一个 NodeList 集合。

当然,我们既然有 length 属性,那必然可以返回某一个节点,不然怎么叫“类数组对象”呢?

我们可以使用 collection.item(index) 或者 collection[index] 返回节点中某一个我们需要的节点。我们一般使用后者,因为它更方便。

还是上面的例子,我们来返回其中的一个节点吧:

console.log(ul.childNodes[2]);

最终返回结果:

好了,我们再来说说 querySelectorAll 为什么是静态的吧,我们来证明它。

首先,我们先获取 ul 列表中所有的 li,接着输出它:

let lis = document.querySelectorAll('li');
console.log(lis);

结果如下:

NodeList 和 HTMLCollection_第2张图片

而此时,我们在 ul 中动态地添加一个 li,并输出它 :

let li = document.createElement('li');
ul.appendChild(li);
li.innerHTML = 'Others';
console.log(lis);

最终结果如下:

NodeList 和 HTMLCollection_第3张图片

第二次的输出结果仍然是 3 个,而我们的 HTML 结构中却多了一个 li。 这就证明了,querySelectorAll 确实是一个静态方法。


HTMLCollection

HTMLCollection 对象是元素的集合。

注意它们之间的区别:NodeList 返回的是各节点;而 HTMLCollection 返回的是元素节点。

官方文档中有下列这句话,需要我们谨慎对待它:

HTMLCollection 是一个历史的工件,我们不能从 web 中摆脱它。虽然开发人员当然欢迎继续使用它,但新的 API 标准设计者不应该使用它。

同样的,它也拥有 length 属性,以及可以使用方括号[] 来访问其中的某一特定元素。

我们来看它和 NodeList 的区别吧。同样还是我们上面提到的那个 ul 列表:

let ul = document.getElementById('ul');
console.log(ul.children);

这一次,我们将 childNodes 换成了 children。它的结果发生了变化:

NodeList 和 HTMLCollection_第4张图片

这次我们也很清楚的看到了,它变成了 HTMLColletion。

至于这两个集合之间的关联,那是历史问题了,这里就不再做深究了。你只需要知道 NodeList 最初设计是给 XML 使用的,而 DOM 中就会返回元素节点和文本节点,通常就产生了我们不想要的东西,比如 IE6 ~ 8 会返回我们的注释,也将它们作为了节点;因此,后来也就诞生了 HTMLCollection,它就只返回元素节点,这通常是我们想要的。例如 getElements* 系列:document.getElementsByTagNamedocument.getElementsByClassNamedocument.getElementsByName 等等。

其它的就不需要知道了。本节到此结束。

你可能感兴趣的:(NodeList 和 HTMLCollection)