2022 年 10 月 14 日

DOM 树

HTML 文档的主干是标签。

根据文档对象模型 (DOM),每个 HTML 标签都是一个对象。嵌套标签是封闭标签的“子级”。标签内的文本也是一个对象。

所有这些对象都可以使用 JavaScript 访问,我们可以使用它们来修改页面。

例如,document.body 是表示 <body> 标签的对象。

运行此代码会使 <body> 在 3 秒钟内变为红色

document.body.style.background = 'red'; // make the background red

setTimeout(() => document.body.style.background = '', 3000); // return back

这里我们使用 style.background 更改 document.body 的背景颜色,但还有许多其他属性,例如

  • innerHTML – 节点的 HTML 内容。
  • offsetWidth – 节点宽度(以像素为单位)
  • …等等。

我们很快就会学习更多操作 DOM 的方法,但首先我们需要了解其结构。

DOM 的示例

让我们从以下简单的文档开始

<!DOCTYPE HTML>
<html>
<head>
  <title>About elk</title>
</head>
<body>
  The truth about elk.
</body>
</html>

DOM 将 HTML 表示为标签的树结构。如下所示

在上面的图片中,你可以单击元素节点,它们的子节点将打开/折叠。

每个树节点都是一个对象。

标签是元素节点(或仅仅是元素),并形成树结构:<html> 在根部,然后 <head><body> 是它的子节点,等等。

元素内的文本形成文本节点,标记为 #text。文本节点仅包含一个字符串。它可能没有子节点,并且始终是树的叶子。

例如,<title> 标签的文本是 "关于 elk"

请注意文本节点中的特殊字符

  • 换行符:(在 JavaScript 中称为 \n
  • 空格:

空格和换行符是完全有效的字符,就像字母和数字一样。它们形成文本节点并成为 DOM 的一部分。因此,例如,在上面的示例中,<head> 标签在 <title> 之前包含一些空格,并且该文本成为 #text 节点(它仅包含换行符和一些空格)。

只有两个顶级排除项

  1. 由于历史原因,<head> 之前的空格和换行符被忽略。
  2. 如果我们在 </body> 之后放置一些内容,那么它将根据 HTML 规范自动移动到 body 内部,在末尾,因为所有内容都必须在 <body> 内。因此,</body> 之后不能有任何空格。

在其他情况下,一切都非常简单——如果文档中存在空格(就像任何字符一样),那么它们将成为 DOM 中的文本节点,如果我们删除它们,那么将不会有任何空格。

这里没有仅空格的文本节点

<!DOCTYPE HTML>
<html><head><title>About elk</title></head><body>The truth about elk.</body></html>
字符串开头/结尾处的空格和仅空格的文本节点通常隐藏在工具中

通常使用 DOM 的浏览器工具(很快将介绍)不会显示文本开头/结尾处的空格和标签之间的空文本节点(换行符)。

开发者工具通过这种方式节省屏幕空间。

在进一步的 DOM 图片中,当它们不相关时,我们有时会省略它们。此类空格通常不会影响文档的显示方式。

自动更正

如果浏览器遇到格式错误的 HTML,它会在生成 DOM 时自动更正它。

例如,最上面的标签始终是 <html>。即使它不存在于文档中,它也会存在于 DOM 中,因为浏览器会创建它。<body> 也一样。

例如,如果 HTML 文件是单个单词 "Hello",浏览器会将其包装到 <html><body> 中,并添加必需的 <head>,并且 DOM 将是

在生成 DOM 时,浏览器会自动处理文档中的错误、关闭标签等。

带有未关闭标签的文档

<p>Hello
<li>Mom
<li>and
<li>Dad

…当浏览器读取标记并恢复缺失部分时,将变成一个正常的 DOM

表格始终具有 <tbody>

表格是一个有趣的“特例”。根据 DOM 规范,它们必须具有 <tbody> 标记,但 HTML 文本可以省略它。然后,浏览器会自动在 DOM 中创建 <tbody>

对于 HTML

<table id="table"><tr><td>1</td></tr></table>

DOM 结构将是

看到了吗?<tbody> 凭空出现了。在处理表格时,我们应该记住这一点,以避免意外。

其他节点类型

除了元素和文本节点之外,还有一些其他节点类型。

例如,注释

<!DOCTYPE HTML>
<html>
<body>
  The truth about elk.
  <ol>
    <li>An elk is a smart</li>
    <!-- comment -->
    <li>...and cunning animal!</li>
  </ol>
</body>
</html>

我们可以在此看到一个新的树节点类型——注释节点,标记为 #comment,位于两个文本节点之间。

我们可能会想——为什么将注释添加到 DOM?它不会以任何方式影响可视化表示。但有一条规则——如果 HTML 中有内容,那么它也必须在 DOM 树中。

HTML 中的一切,甚至是注释,都成为 DOM 的一部分。

即使是 HTML 最开始的 <!DOCTYPE...> 指令也是一个 DOM 节点。它在 DOM 树中位于 <html> 之前。很少有人知道这一点。我们不会触及该节点,我们甚至不会在图表中绘制它,但它就在那里。

形式上,表示整个文档的 document 对象也是一个 DOM 节点。

12 种节点类型。在实践中,我们通常使用其中的 4 种

  1. document——进入 DOM 的“入口点”。
  2. 元素节点——HTML 标记,树构建块。
  3. 文本节点——包含文本。
  4. 注释——有时我们可以将信息放在那里,它不会显示,但 JS 可以从 DOM 中读取它。

自己看看

要实时查看 DOM 结构,请尝试使用 实时 DOM 查看器。只需在文档中输入,它就会立即显示为 DOM。

探索 DOM 的另一种方法是使用浏览器开发者工具。实际上,这是我们在开发时使用的工具。

为此,请打开网页 elk.html,打开浏览器开发者工具并切换到“元素”选项卡。

它应该如下所示

你可以看到 DOM,单击元素,查看它们的详细信息等等。

请注意,开发者工具中的 DOM 结构已简化。文本节点仅显示为文本。并且根本没有“空白”(仅空格)文本节点。这很好,因为大多数时候我们对元素节点感兴趣。

单击左上角的 按钮,我们可以使用鼠标(或其他指针设备)从网页中选择一个节点并“检查”它(在“元素”选项卡中滚动到它)。当我们有一个巨大的 HTML 页面(以及相应的巨大 DOM)并希望看到其中特定元素的位置时,这非常有用。

另一种方法是右键单击网页并在上下文菜单中选择“检查”。

在工具的右侧有以下子选项卡

  • 样式 – 我们可以逐条规则地查看应用于当前元素的 CSS,包括内置规则(灰色)。几乎所有内容都可以就地编辑,包括下方框的尺寸/边距/内边距。
  • 已计算 – 按属性查看应用于元素的 CSS:对于每个属性,我们可以看到提供该属性的规则(包括 CSS 继承等)。
  • 事件侦听器 – 查看附加到 DOM 元素的事件侦听器(我们将在本教程的下一部分中介绍它们)。
  • …等等。

研究它们的最佳方法是四处点击。大多数值都可以就地编辑。

与控制台交互

在处理 DOM 时,我们可能还想对其应用 JavaScript。例如:获取一个节点并运行一些代码来修改它,以查看结果。以下是几个在元素选项卡和控制台之间切换的技巧。

首先

  1. 在元素选项卡中选择第一个 <li>
  2. Esc – 它将在元素选项卡正下方打开控制台。

现在,最后选择的元素可用作 $0,之前选择的元素可用作 $1 等。

我们可以在它们上运行命令。例如,$0.style.background = 'red' 使选定的列表项变为红色,如下所示

这就是在控制台中从元素获取节点的方法。

还有一条返回路径。如果有一个引用 DOM 节点的变量,那么我们可以在控制台中使用命令 inspect(node) 在元素窗格中查看它。

或者,我们只需在控制台中输出 DOM 节点并探索“就地”,如下面的 document.body

当然,这是为了调试目的。从下一章开始,我们将使用 JavaScript 访问和修改 DOM。

浏览器开发者工具在开发中提供了极大的帮助:我们可以探索 DOM,尝试一些操作并查看出了什么问题。

总结

HTML/XML 文档在浏览器中表示为 DOM 树。

  • 标签变为元素节点并形成结构。
  • 文本变为文本节点。
  • …等,HTML 中的任何内容在 DOM 中都有其位置,甚至注释也是如此。

我们可以使用开发者工具来检查 DOM 并手动修改它。

在这里,我们介绍了基础知识,即最常用和最重要的入门操作。在 https://developers.google.com/web/tools/chrome-devtools 上有关于 Chrome 开发者工具的详尽文档。学习这些工具的最佳方法是单击此处和那里,阅读菜单:大多数选项都很明显。稍后,当你大致了解它们时,阅读文档并了解其余内容。

DOM 节点具有属性和方法,允许我们在它们之间穿行、修改它们、在页面上移动,等等。我们将在下一章中详细了解它们。

教程地图

评论

在评论之前阅读此内容…
  • 如果您有改进建议 - 请 提交 GitHub 问题或提交拉取请求,而不是发表评论。
  • 如果您无法理解文章中的内容 - 请详细说明。
  • 要插入一些代码,请使用 <code> 标记,对于多行 - 将它们包装在 <pre> 标记中,对于超过 10 行 - 使用沙箱 (plnkrjsbincodepen…)