原文链接:https://javascript.info/dom-nodes,translate with ❤️ by zhangbao.
HTML 文档的骨干 是标签。
根据文档对象模型(DOM),每个 HTML 标签都是一个对象。嵌套标签被称为封闭标签的“孩子”。
标签里的文本也是对象。
所有这些对象都可以通过 JavaScript 获取。
DOM 树的例子
<!DOCTYPE html>
<html>
<head>
<title>About elks</title>
</head>
<body>
<p>The truth about elks.</p>
</body>
</html>
用 DOM 树表示这段代码是这样的:
▼HTML
▼HEAD
#text ↵␣␣
▼TITLE
#text About elks
#text ↵
#text ↵
▼BODY
#text ↵␣␣
P
#text The truth about elks.
#text ↵↵
标签称为元素节点(或简称元素)。嵌套标签是所在封闭标签的孩子。结果,我们就得到一个元素树了:<html>
是根元素,<head>
和 <body>
是它的孩子等。
元素内的文本成为文本节点,标记为 #text
,文本节点仅包含字符串。它可能没有孩子,作为元素树的叶子节点存在。
比如:<title>
标签包含文本节点 "About elks"
。
下面给出了在上面文本节点中出现的特殊字符的意思:
换行符:
↵
(也就是\n
)空格符:
␣
空格和换行符都属于有效字符。它们组成文本节点,并成为 DOM 树的一部分。比如,前面例子里,<head>
标签里的 <title>
前面有一个换行符和两个空格符组成的文本节点 #text
。
我们还能看到 <body>
的最后一个子节点的内容是 ↵↵
,第一个 ↵
是 指 </p>
标签后面的换行符,第二个 ↵
是指 </body>
后面的换行符。
但有两种例外情况:
在
<head>
标签之前的空格和换行符,由于历史原因,会被忽略,如果我们在
</body>
之后写了代码,都会被自动移动到<body>
中,因为 HTML 规范要求所有的内容都必须在<body>
中。所以,</body>
之后没有空格。
在其他情况下,一切都很简单——如果文档中有空格(就像任何字符一样),那么它们就会成为 DOM 中的文本节点,如果我们删除它们,也就没有了。
下面是不存在空格的,纯文本节点的 HTML 代码例子:
<!DOCTYPE html>
<html><head><title>About elks</title></head><body><p>The truth about elks.</p></body></html>
对应 DOM 树结构如下:
▼HTML
▼HEAD
▼TITLE
#text About elks
▼BODY
P
#text The truth about elks.
边缘空格和中间空文本通常会被开发者工具隐藏
展示 DOM 的浏览器工具(很快就会介绍)通常不会显示文本开头/结尾处的空格,也不会显示标签之间(换行)的空文本节点。
因为这些内容都是修饰性的,(几乎)不会影响最终的 HTML 内容展现。
为了保证后面的行文简洁,之后的 DOM 树结构里会忽略这些内容。
自动校正
浏览器生成 DOM 树的时候,对于不正确的 HTML 结构会自动校正。
比如:顶部标签总是 <html>
,即使代码里没有写,浏览器生成 DOM 树的时候,也会创建它。然后是 <body>
。
写个例子:HTML 文件里只有一个 "Hello"
,浏览器会将其封装进 <html>
和 <body>
中。
▼HTML
▼HEAD
▼BODY
#text Hello
在生成 DOM 的时候,浏览器自动处理文档中的错处,在必要时闭合标签等。
这样一个”无效”的文档:
<p>Hello
<li>Mom
<li>and
<li>Dad
在经过浏览器校正之后,DOM 树结构变成如下这样:
▼HTML
▼HEAD
▼BODY
▼P
#text Hello
▼LI
#text Mom
▼LI
#text and
▼LI
#text Dad
表格总包有 `` 标签
一个有趣的“特别案例”是表格。根据 DOM 规范,一个表格必须包含
标签,虽然 HTML 官方规范里在使用时常常忽略,不过浏览器总是会在最终的 DOM 渲染树里自动插入 </tbody>
标签。如下的 HTML 结构:
<table id="table"><tr><td>1</td></tr></table>
渲染出来的 DOM 结构将是:
其他节点类型
为“DOM 树的例子”一节中的文档,添加更多标签和注释。
<!DOCTYPE html>
<html>
<body>
<p>The truth about elks.</p>
<ol>
<li>An elk is a smart</li>
<!-- comment -->
<li>...and cunning animal!</li>
</ol>
</body>
</html>
▼HTML
▼HEAD
▼BODY
#text ↵␣␣
▼P
#text The truth about elks.
#text ↵␣␣
▼OL
#text ↵␣␣␣␣
▼LI
#text An elk is a smart
#comment comment
#text ↵␣␣␣␣
▼LI
#text ...and cunning animal!
#text ↵␣␣
#text ↵↵
我们引入了一个新的节点类型——注释节点,标记为 #comment
。
我们可能感觉奇怪,为什么 DOM 里还会有注释节点呢,毕竟没有它也不会影响页面最终展示效果的。但就是这样,这是规则:HTML 文档里的任何内容,甚至注释,在对应的 DOM 树中都有一个节点与之对应。
甚至 HTML 开头的文档声明 <!DOCTYPE html>
都是 DOM 树中的一个节点,<html>
紧随其后,我们不打算讲它,所有 DOM 树中也没有画出它,但它确实是存在的。
document
对象代表整个文档,并且它也是一个 DOM 节点。
一共有 12 个节点类型。实践中,我们常接触 4 个:
document
:DOM 树的“入口”。元素节点:HTML 标签,DOM 树的构建块。
文本节点:文本。
注释:有时我们可以将一些提示信息放在那里,它不会显示,但可以用 JavaScript 从 DOM 中读到它。
自己看
这里有一个网址 Live DOM Viewer,是一个查看文档结构的小工具。输入你的 HTML 代码,程序就会立刻输出对应的 DOM 树结构,可以点开感受一下。
在浏览器中检查
另一种查看 DOM 树的方式是使用浏览器提供的开发者工具。实际开发中,我们也最常用到它。
点开 elks.html 页面,打开浏览器开发者工具,切换至 Elements 选项卡,你就能看到如下的视图:
你可以看到 DOM 树结构,再点击元素的话,能看到关于该元素的更多信息。
请注意,在此展示的 DOM 结构是简化的。文本节点只作为一个纯文本展示,这里也没有“空白”(仅包含空格)文本节点。这很好,因为多数时间,我们关心的是元素节点。
单击开发者工具左上角 按钮后,我们就可以使用鼠标(或其他指针设备)从网页中选择节点并“检查”它(在“元素”选项卡中滚动到它)。在我们处于一个庞大的 HTML 页面中(对应巨大 DOM)并且希望观察其中某个特定元素位置时,非常有用。
另一个查看元素的方式,是在网页中的元素上右键,点击菜单列表中的“检查”选项。
工具栏的右侧包含如下的子选项卡:
Styles:我们可以看到当前元素应用的所有 CSS 样式,包括浏览器内置样式(灰色背景标识)。几乎所有样式都是可编辑的,比如盒子的
width
/height
/margin
/padding
。Computed:当前元素的计算属性值,即元素最终应用的样式(包括继承过来的样式)。
Event Listeners:当前元素绑定的事件处理程序(会在本教程的下一部分讲解)。
……
最好的学习方式就是点来点去,许多值都是可以直接编辑的。
操作控制台
在我们观察 DOM 节点时,也会碰到要对其进行 JavaScript 操作的需要。像:获取一个节点,并对其进行一些修改。下面举了一个结合使用 Elements
选项卡和控制台的例子。
在
Elements
选项卡中选择第一个<li>
。按下
ESC
,会发现控制台在Elements
选项卡下打开了。
现在我们选中的元素可以通过 $0
在控制台中被访问到。而之前选择的那个元素使用 $1
即可访问,以此类推。
我们可以在这些元素上执行命令。比如:$0.style.background = 'red'
,就会发现被我们选中的元素背景变红了。
这也表示,我们通过一个变量引用了页面中的 DOM 元素。我们还可以用 inspect(node)
去监听到 Elements 选项卡里的特定元素(跟我们手动点击元素的效果类似)。
或者我们可以在控制台直接输出它,“原地”检查,以下面的 document.body
为例:
上面介绍这些只是为了方便我们 debug。下一章我们介绍怎么使用 JavaScript 修改 DOM。
浏览器开发者工具在我们开发中会给我们带来很大的帮助:帮助我们查看 DOM,观察程序里哪个地方出了问题。
总结
HTML/XML 文档会被浏览器解析成一个 DOM 树结构。
标签变成了元素节点。
文本变成文本节点。
……任何在 HTML 文档中的内容在 DOM 中都有一个节点与之对应,甚至是注释。
我们可以通过开发者工具观察和手动修改 DOM。关于 Chrome 开发工具有大量的文档,地址在 https://developers.google.com/web/tools/chrome-devtools。最好地学习工具的方式就是点来点去,阅读菜单栏,许多选项一看就能懂。
DOM 节点包含许多属性和方法,允许在它们之做遍历、修改、移动页面内容等操作。我们将在下一章介绍。
(完)