沿着树移动
DOM 节点包含了许多指向相邻节点的链接。下面的图表展示了这一点。
尽管图表中每种类型的节点只显示出一条链接,但每个节点都有parentNode
属性,指向一个节点,它是这个节点的一部分。类似的,每个元素节点(节点类型为 1)均包含childNodes
属性,该属性指向一个类数组对象,用于保存其子节点。
理论上,你可以通过父子之间的链接移动到树中的任何地方。但 JavaScript 也提供了一些更加方便的额外链接。firstChild
属性和lastChild
属性分别指向第一个子节点和最后一个子节点,若没有子节点则值为null
。类似的,previousSibling
和nextSibling
指向相邻节点,分别指向拥有相同父亲的前一个节点和后一个节点。对于第一个子节点,previousSibling
是null
,而最后一个子节点的nextSibling
则是null
。
也存在children
属性,它就像childNodes
,但只包含元素(类型为 1)子节点,而不包含其他类型的子节点。 当你对文本节点不感兴趣时,这可能很有用。
处理像这样的嵌套数据结构时,递归函数通常很有用。 以下函数在文档中扫描包含给定字符串的文本节点,并在找到一个时返回true
:
function talksAbout(node, string) {
if (node.nodeType == document.ELEMENT_NODE) {
for (let i = 0; i < node.childNodes.length; i++) {
if (talksAbout(node.childNodes[i], string)) {
return true;
}
}
return false;
} else if (node.nodeType == document.TEXT_NODE) {
return node.nodeValue.indexOf(string) > -1;
}
}
console.log(talksAbout(document.body, "book"));
// → true
因为childNodes
不是真正的数组,所以我们不能用for/of
来遍历它,并且必须使用普通的for
循环遍历索引范围。
文本节点的nodeValue
属性保存它所表示的文本字符串。