DOM-节点集合

内容列表

当从文档树中选取成组的节点或者使用预定义的节点集合时,这些节点都是放在 NodeList 或者一个 HTMLCollecton 之中,而不是一个数组(Array)中。

节点集合

我们将一个 NodeList 或者 HTMLCollecton 称为节点集合,也就是类数组的节点对象集合。节点集合一般有以下特征:

  • 实时或静态

    这意味着在集合中包含的节点对象们或是实时文档树的某一部分,或是某一实时文档树的快照。

  • 顺序一致性

    默认情况下,集合中的节点对象以其所在 DOM 树中的顺序排序,这就意味着这个顺序与从树到分支的线性路径吻合。

  • length 属性

    我们可以通过其 length 属性获取该节点集合中的节点数目。

注意,NodeListHTMLCollection 都是实时列表。

获取所有直属子节点

利用节点对象身上的 childNodes 属性会获取一个类数组的包含直属(第一代)子节点的列表,也就是 NodeList

<body>
    <p>Hello,World!</p>
</body>
<script>
    // 输出<body>元素节点的所有直属子节点集合
    console.log(document.body.childNodes);
    // 输出为 [text, p, text, script]
</script>

要注意的是,它并不是一个纯数组,而是类数组的集合。为什么有两个子节点是文本(Text)节点,是因为 <p> 标签前后都有回车符和空格。

childNodes 属性返回的 NodeList 仅包含直属子节点;而且不仅包含元素(Element)节点,还包含其他所有类型节点,例如文本(Text)节点、注释(Comment)节点。

获取所有元素节点集合

对于一个元素节点对象,我们可以利用其 children 属性获取其所有的 直属子元素节点。而且还有以下几个文档对象属性可以获取预定义的元素节点集合:

  • document.all

    获取 HTML 文档中所有元素节点的集合。

  • document.forms

    获取 HTML 文档中所有(from)元素。

  • document.images

    获取 HTML 文档中所有(img)元素。

  • document.links

    获取 HTML 文档中所有(a)元素。

  • document.scripts

    获取 HTML 文档中所有(script)元素。

  • document.styleSheets

    获取 HTML 文档中所有(link、style)元素。

以上类数组列表中,document.all 构建自 HTMLAllCollectionstyleSheets 构建自 StyleSheetList;其他的均构建自 HTMLCollection

将节点集合转换成数组

节点集合(NodeList 与 HTMLCollection)都是类数组,但并不是真正的数组,后者继承数组的方法。我们做以验证:

<body>
    <a href=""></a>
<body>
<script>
    // 验证 NodeList
    console.log(Array.isArray(document.body.childNodes)); // 输出false

    // 验证 HTMLCollection
    console.log(Array.isArray(document.links)); // 输出false
</script>

如何将一个类数组列表转换成真正的 javascript 数组?

我们只需要将类数组列表传给 call() 或者 apply(),在它们中调用一个数组方法,它们就会返回一个未经修改的真正的 javascript 数组。

<body>
    <a href=""></a>
<body>
<script>
    // NodeList 转换成数组并验证
    console.log(Array.isArray(Array.prototype.slice.call(document.body.childNodes)));
    // 输出true

    // HTMLCollection 转换成数组并验证
    console.log(Array.isArray(Array.prototype.slice.call(document.links)));
    // 输出true
</script>

将其转换为真正的 javascript 数组有以下好处:

  • 获取快照

    NodeList、HTMLCollection 都是实时列表,这么做使我们能够获取该列表的快照,不与实时 DOM 绑定。

  • 方便操作

    转换成数组之后,我们可以使用数组的方法,例如 forEach、pop、map、reduce 等。

结语

其实节点集合我们通常可能不太关注,我们大多数时候关注的都是单个节点。但是,在某些需要批量操作的场景,这时候节点集合倒是不错的选择。

参考

  • 《DOM 启蒙》,Cody Lindley,陈养剑 译

相关

一些互联网名词

互联网时代是个新概念频出的时代,每年有相当多的新名词诞生,而诸多与商业活动紧密相关的词汇了解一下有助于我们熟悉日常工作中接触的东西。

了解更多

那些年之电子产品

把这几年工作上学买过的电子产品整理下;

大学开始至今年代久远,整理的时间不一定对的上,简单整理一下当手帐册供日后做纪念:

了解更多

DOM-加载 JavaScript

页面的动态交互离不开 Javascript,将 js 脚本引入页面时会阻塞页面加载,在某些时候我们则可以选择异步加载 js 脚本。

了解更多