介绍
本系列的上一本教程 如何在 DOM 中访问元素涵盖了如何使用文档
对象的内置方法以通过ID、类、标签名称和查询选择器访问HTML元素。
通常,你会想通过DOM进行移动,而不会提前指定每个元素。学习如何上下导航DOM树,并从分支到分支,对于了解如何使用JavaScript和HTML至关重要。
在本教程中,我们将讨论如何穿越DOM(也称为步行或导航DOM)与父母,子女和兄弟姐妹属性。
设置
首先,我们将创建一个名为nodes.html
的新文件,由以下代码组成。
1[label nodes.html]
2<!DOCTYPE html>
3<html>
4
5<head>
6 <title>Learning About Nodes</title>
7
8 <style>
9 * { border: 2px solid #dedede; padding: 15px; margin: 15px; }
10 html { margin: 0; padding: 0; }
11 body { max-width: 600px; font-family: sans-serif; color: #333; }
12 </style>
13</head>
14
15<body>
16 <h1>Shark World</h1>
17 <p>The world's leading source on <strong>shark</strong> related information.</p>
18 <h2>Types of Sharks</h2>
19 <ul>
20 <li>Hammerhead</li>
21 <li>Tiger</li>
22 <li>Great White</li>
23 </ul>
24</body>
25
26<script>
27 const h1 = document.getElementsByTagName('h1')[0];
28 const p = document.getElementsByTagName('p')[0];
29 const ul = document.getElementsByTagName('ul')[0];
30</script>
31
32</html>
当我们在网页浏览器中加载文件时,我们将看到像下面的屏幕截图的渲染。
在这个示例网站中,我们有一个包含几个元素的HTML文档。在一个风格
标签中添加了一些基本的CSS,以使每个元素显而易见,并且在脚本
中创建了一些变量,以便轻松访问几个元素。
根节点
该文档
对象是 DOM 中的每个节点的根源。该对象实际上是窗口
对象的属性,它是浏览器中代表卡的全球顶级对象。 窗口对象可以访问工具栏、窗口的高度和宽度、提示和警告等信息。
下面是由每个文档所包含的根元素组成的图表,即使一个空的HTML文件被加载到浏览器中,这三个节点也会被添加到DOM中。
Property | Node | Node Type |
---|---|---|
document | #document | DOCUMENT_NODE |
document.documentElement | html | ELEMENT_NODE |
document.head | head | ELEMENT_NODE |
document.body | body | ELEMENT_NODE |
由于html
、head
和body
元素非常常见,因此它们在文档
上有自己的属性。
在 DevTools 中打开 Console 并通过提交它们并查看输出来测试这四个属性中的每一个。
父母节点
DOM中的节点被称为父母、子女和兄弟姐妹,取决于它们与其他节点的关系。任何节点的 父母是位于其一级以上的节点,或者更接近 DOM 层次中的文档
。
Property | Gets |
---|---|
parentNode | Parent Node |
parentElement | Parent Element Node |
在我们的nodes.html
示例中:
*html
是头
、身体
和脚本
的母体。
*身体
是h1
,h2
,p
和ul
的母体,但不是li
,因为li
是身体
的两层。
我们可以通过parentNode
属性来测试我们的p
元素的母体是什么。
1p.parentNode;
1[secondary_label Output]
2► <body>...</body>
p
的父母是身体
,但我们怎么能得到两个以上的祖父母呢?我们可以通过链接财产来做到这一点。
1p.parentNode.parentNode;
1[secondary_label Output]
2► <html>...</html>
使用parentNode
两次,我们找到了p
的祖父母。
有一些属性可以检索节点的母体,但它们之间只有一个小区别,如下文所示。
1// Assign html object to html variable
2const html = document.documentElement;
3
4console.log(html.parentNode); // > #document
5console.log(html.parentElement); // > null
几乎任何节点的家长是元素节点,因为文本和评论不能是其他节点的家长,然而,html的家长是文档节点,所以parentElement
返回null
。
儿童节点
一个节点的孩子
是位于其下方一个级别的节点,任何超过一个层次的节点通常被称为后代。
Property | Gets |
---|---|
childNodes | Child Nodes |
firstChild | First Child Node |
lastChild | Last Child Node |
children | Element Child Nodes |
firstElementChild | First Child Element Node |
lastElementChild | Last Child Element Node |
childNodes
属性将返回一个节点的每个孩子的直播列表.你可以期望ul
元素获得三个li
元素。
1ul.childNodes;
1[secondary_label Output]
2► (7) [text, li, text, li, text, li, text]
除了三个li
元素之外,它还获得了四个文本节点,这是因为我们写了自己的HTML(它不是由JavaScript生成的),并且元素之间的间隔在DOM中被计算为文本节点。
如果我们试图使用firstChild
属性改变第一个孩子节点的背景颜色,它会失败,因为第一个节点是文本。
1ul.firstChild.style.background = 'yellow';
1[secondary_label Output]
2Uncaught TypeError: Cannot set property 'background' of undefined
在这些类型的情况下,只有元素节点可以检索children
,firstElementChild
和lastElementChild
属性,而ul.children
只能返回三个li
元素。
使用firstElementChild
,我们可以改变ul
中的第一个li
的背景颜色。
1ul.firstElementChild.style.background = 'yellow';
当您运行上述代码时,您的网页将被更新以更改背景颜色。
在做基本的 DOM 操作时,如在本示例中,元素特定的属性非常有用. 在 JavaScript 生成的 Web 应用程序中,选择所有节点的属性更有可能被使用,因为白色空间的新闻和入口在这种情况下不会存在。
一个 for...of
循环可以用来迭代所有孩子
元素。
1for (let element of ul.children) {
2 element.style.background = 'yellow';
3}
现在,每个儿童元素都将有一个黄色背景。
由于我们的p
元素有文本和元素,所以childNodes
属性有助于访问这些信息。
1for (let element of p.childNodes) {
2 console.log(element);
3}
1[secondary_label Output]
2"The world's leading source on "
3<strong>shark</strong>
4" related information."
「childNodes」和「children」不返回具有所有 Array 属性和方法的数组,但它们看起来和行为类似于 JavaScript 数组。
1document.body.children[3].lastElementChild.style.background = 'fuchsia';
上面的代码会找到身体
的第四个孩子元素(ul
)的最后一个元素的孩子(li
)并应用一个风格。
使用家长和儿童属性,您可以在 DOM 中检索任何节点。
兄弟节点
节点的 siblings 是 DOM 中的相同树位上的任何节点. 兄弟姐妹不必是相同类型的节点 - 文本,元素和评论节点都可以是兄弟姐妹。
Property | Gets |
---|---|
previousSibling | Previous Sibling Node |
nextSibling | Next Sibling Node |
previousElementSibling | Previous Sibling Element Node |
nextElementSibling | Next Sibling Element Node |
兄弟属性与孩子节点相同,因为有所有节点穿过的一组属性,只有元素节点的一组属性。 previousSibling' 和
nextSibling' 将获得即时先行或跟随指定的节点的下一个节点,而 previousElementSibling' 和
nextElementSibling' 将只获得元素节点。
在我们的nodes.html
示例中,让我们选择ul
的中间元素。
1const tiger = ul.children[1];
由于我们从头开始创建了DOM,而不是作为一个JavaScriptWeb应用程序,所以我们需要使用元素姐妹属性来访问前一个和下一个元素节点,因为DOM中有白色空间。
1tiger.nextElementSibling.style.background = 'coral';
2tiger.previousElementSibling.style.background = 'aquamarine';
运行此代码应该将珊瑚
应用于Hammerhead
的背景和aquamarine
应用于Great White
的背景。
兄弟属性可以链接在一起,就像父母和节点属性一样。
结论
在本教程中,我们涵盖了如何访问每个HTML文档的根节点,以及如何通过父母,子女和兄弟姐妹属性的DOM树。
借助您在 如何在DOM中访问元素和本教程中学到的内容,您应该能够安全地访问任何网站的DOM中的任何节点。