正在加载...

HTML DOM

磁盘上的 HTML 文件只保存字符。浏览器据此造出一棵活的树,这棵树就是 DOM。站牌玻璃上有两行:标题 Market,备注 Stand clear。页面已经打开时,document 就在。new document() 会抛错,new Document() 则是一份空文档,不是这块站牌。

这是一棵树,不是取整

Math 那一页是向一个共用对象要数字。这里既不取整宽度,也不用 new Date 造一个时刻。从 document 往下走:html 元素,然后 head 挨着 body,然后标题挨着备注。用多种办法选取元素、改标记、新建节点,都在后面的页面。这一页只认树的形状,并读两个节点。

每一块在站牌上的位置

每一行都是你能指到的一处。最后一列是容易走错的地方。

📊 这块站牌上的位置

位置 手里拿着什么 在这块站牌上 容易搞混
document 树本身 入口,没有标签名 把它当成 body
document.documentElement html 元素 标签 HTML 把它叫成标题
document.head head 元素 body 的兄弟 在这里找 Market
document.body body 元素 标题的父元素 一个文本节点
h1#stop 标题元素 文本 Market 磁盘上保存的文件
标题里的文字 只有字符 词 Market 一个带 id 的元素

标题和备注都是 body 的元素子节点,所以它们是兄弟。词 Market 不是备注的兄弟。它是标题里面的文本。tagName 返回大写,所以 html 元素报 HTML。document 这个节点没有标签,也没有父元素。

树顶上的三个名字

这三个属性点名最外层的元素。玻璃上的标题不在这三个里面。

外层元素

javascript
console.log(document.documentElement.tagName);
console.log(document.head.tagName);
console.log(document.body.tagName);

三行分别是 HTML、HEAD、BODY。head 和 body 都是 html 元素的子节点,所以互为兄弟。Market 不在 head 里。head 里的页签标题是另一串文字,不是玻璃上的标题。

标题这一家

id stop 是标题元素的把手。它的父元素是 body。下一个元素兄弟是备注。

父元素和兄弟

javascript
let stop = document.getElementById("stop");
console.log(stop.parentElement.tagName);
console.log(stop.nextElementSibling.id);

第一行是 BODY。第二行是 note。nextElementSibling 会跳过换行,落在段落上。上一个元素兄弟是 null,因为 body 里标题前面没有别的元素。

文字和把手是两回事

读元素,和读里面的字符,不是同一次读取。

文本和 id

javascript
let stop = document.getElementById("stop");
console.log(stop.textContent);
console.log(stop.id);

第一行是 Market。第二行是 stop。textContent 是字符。id 是把手。备注写的是 Stand clear,这串文字不在标题上。

先数元素,再数所有节点

children 只数元素子节点。childNodes 把文本节点也数进去,包括站牌文件里的换行。这段代码要在只含标题和备注的 body 上跑,不要在本课页面上跑,也不要在下面那份读出文件上跑。

两个长度

javascript
console.log(document.body.children.length);
console.log(document.body.childNodes.length);

标题前有一次换行,两个元素之间有一次,备注后再有一次,那么 children.length 是 2,childNodes.length 是 5。多出来的三个节点是文本,里面只有空白。把两个标签贴到同一行,这些文本节点就没了,两个长度会重合。

站牌上没有的名字

去要一个文件里从没写过的 id。

缺失的 id

javascript
console.log(document.getElementById("platform"));
console.log(document.getElementById("stop") === null);

第一行是 null。第二行是 false,因为 stop 确实在。null 的意思是没有这个元素,不是一个空标题。给 textContent 赋一段新字符串,改的是浏览器里的活树。磁盘上的 HTML 文件仍然写着 Market。

页面上的一行

第三个段落写出父元素的标签名和标题文字。脚本放在 body 末尾,等这些元素已经在树上。

父元素和标题

html
<!DOCTYPE html>
<html>
<head>
<title>dom — page</title>
</head>
<body>
<h1 id="stop">Market</h1>
<p id="note">Stand clear</p>
<p id="board">…</p>
<script>
let stop = document.getElementById("stop");
let board = document.getElementById("board");
board.textContent = stop.parentElement.tagName + " / " + stop.textContent;
</script>
</body>
</html>

段落显示 BODY / Market。这份文件在脚本之前,body 里有三个元素,所以长度 2 不属于它。script 元素本身也是一个子节点。下一页会用不止一种办法选取元素。

自己把站牌走一遍

  1. 打出三个外层标签名,期望先是 HTML,然后 HEAD,然后 BODY
  2. 打出标题的父标签,期望 BODY
  3. 打出下一个元素兄弟的 id,期望 note
  4. 打出标题文字,期望 Market,再打出 id,期望 stop
  5. 在只有两个元素的站牌上,期望 children 的长度是 2,childNodes 的长度是 5
  6. 打出缺失的 id,期望 null,再和 stop 比较,期望 false
  7. 读段落,期望 BODY / Market

地方指错了

页面照样打开。你点到的地方不是标题所在。

  • 调用 new document(),或把 new Document() 当成这块站牌
  • 到 document.head 里找 Market
  • 把词 Market 当成备注的元素兄弟
  • 想数上换行在内的每个节点时,却去读 children.length
  • 只想要标题和备注时,却去读 childNodes.length
  • 把缺失 id 得到的 null 当成空字符串
  • 以为写入 textContent 也会改掉磁盘上的文件

把这些分开

  • document 是树;documentElement 是 html 元素
  • head 和 body 是这个 html 元素下面的兄弟
  • 标题的父元素是 body;下一个元素兄弟是备注
  • textContent 是字符;id 是把手
  • children 只有元素;childNodes 包含空白文本
  • 缺失的 id 是 null;保存的文件不是那棵活树
  • 下一页选取元素时,不只有一种 id

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
8
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部