DOM-节点集合
内容列表
当从文档树中选取成组的节点或者使用预定义的节点集合时,这些节点都是放在 NodeList 或者一个 HTMLCollecton 之中,而不是一个数组(Array)中。
节点集合
我们将一个 NodeList
或者 HTMLCollecton
称为节点集合,也就是类数组的节点对象集合。节点集合一般有以下特征:
实时或静态
这意味着在集合中包含的节点对象们或是实时文档树的某一部分,或是某一实时文档树的快照。
顺序一致性
默认情况下,集合中的节点对象以其所在 DOM 树中的顺序排序,这就意味着这个顺序与从树到分支的线性路径吻合。
length 属性
我们可以通过其
length
属性获取该节点集合中的节点数目。
注意,NodeList
与 HTMLCollection
都是实时列表。
获取所有直属子节点
利用节点对象身上的 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
构建自 HTMLAllCollection
;styleSheets
构建自 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,陈养剑 译