文档对象模型, 或 "DOM", 是 web 页面的接口. 它本质上是页面的 API, 允许程序读取和操作页面的内容, 结构和样式. 让我们分解一下.
如何构建 Web 页面?
浏览器如何从一个源 html 文档到在视图中显示一个样式化的交互式页面被称为 "关键呈现路径". 虽然这个过程可以分解为几个步骤, 但正如我在理解关键呈现路径的文章中所述, 这些步骤大致可以分为两个阶段. 第一个阶段涉及浏览器解析文档以确定最终在页面上呈现什么, 第二个阶段涉及浏览器执行呈现.
第一阶段的结果是所谓的 "渲染树". 渲染树是将在页面上呈现的 HTML 元素及其相关样式的表示. 为了构建这个树, 浏览器需要两件事:
1.CSSOM, 与元素相关的样式的表示
2.DOM, 元素的表示
如何创建 DOM?
DOM 是源 HTML 文档的基于对象的表示. 正如我们将在下面看到的, 它有一些不同之处, 但它本质上是试图将 HTML 文档的结构和内容转换为可由各种程序使用的对象模型.
DOM 的对象结构由所谓的 "节点树" 表示. 之所以这样叫它, 是因为它可以被认为是一棵树, 它有一个单一的父茎, 它可以分出几个子枝, 每个子枝都可能有叶子. 在本例中, 父 "茎" 是根元素, 子 "分支" 是嵌套的元素, 而 "叶" 是元素中的内容.
我们以此 HTML 文档为例
- <!doctype HTML>
- <HTML lang="en">
- <head>
- <title>
- My first Web page
- </title>
- </head>
- <body>
- <h1>
- Hello, world!
- </h1>
- <p>
- How are you?
- </p>
- </body>
- </HTML>
本文档可以表示为以下节点树:
DOM 不是什么?
在我上面给出的示例中, DOM 似乎是源 HTML 文档或您所看到的 DevTools 的一对一映射. 但是, 正如我所提到的, 有一些区别. 为了完全理解 DOM 是什么, 我们需要了解它不是什么.
DOM 不是源 HTML
虽然 DOM 是从源 HTML 文档创建的, 但它并不总是完全相同. 在两个实例中, DOM 可以与源 HTML 不同.
当 HTML 无效时
DOM 是有效 HTML 文档的接口. 在创建 DOM 的过程中, 浏览器可能会纠正 HTML 代码中的一些错误.
让我们以这个 HTML 文档为例:
<!doctype HTML> <HTML> Hello, world! </HTML>
文档缺少一个 < head > 和 < body > 元素, 这是有效 HTML 的一个要求. 如果我们查看生成的 DOM 树, 就会发现这已经得到了纠正:
当 DOM 被 JavaScript 修改时
除了作为查看 HTML 文档内容的接口之外, 还可以修改 DOM, 使其成为一种活动资源. 例如, 我们可以使用 JavaScript 为 DOM 创建额外的节点.
var newParagraph = document.createElement("p"); var paragraphContent = document.createTextNode("I'm new!"); newParagraph.appendChild(paragraphContent); document.body.appendChild(newParagraph);
这将会更新 DOM, 但当然不会更新 HTML 文档.
DOM 不是在浏览器中看到的 (即, 渲染树)
你在浏览器视图中看到的是渲染树, 如前所述, 它是 DOM 和 CSSOM 的组合. DOM 与渲染树的真正区别在于, 后者只包含最终将在屏幕上绘制的内容.
[图片上传失败...(image-61c376-1546073073535)]
因为渲染树只关注渲染的内容, 它排除了视觉上隐藏的元素. 例如, 具有与 display: none 样式相关联的元素.
<!doctype HTML> <HTML lang="en"> <head> </head> <body> <h1> Hello, world! </h1> <p style="display: none;"> How are you? </p> </body> </HTML>
DOM 将包含 < p > 元素:
然而, 渲染树, 以及在视图中看到的内容, 将不包含该元素.
DOM 不是 DevTools 中的 DOM
这种差异有点小, 因为 DevTools 元素检查器提供了与浏览器中 DOM 最接近的近似. 但是, DevTools 检查器包含了不在 DOM 中的其他信息.
最好的例子是 CSS 伪元素. 使用::before 和::after 选择器创建的伪元素构成 CSSOM 和渲染树的一部分, 但在技术上不是 DOM 的一部分. 这是因为 DOM 是单独从源 HTML 文档构建的, 不包括应用于元素的样式.
尽管伪元素不是 DOM 的一部分, 但是它们在我们的 devtools 元素检查器中.
这就是 JavaScript 不能以伪元素为目标的原因, 因为它们不是 DOM 的一部分.
总结
DOM 是 HTML 文档的接口. 浏览器使用它作为决定在视图中呈现什么内容的第一步, 并通过 JavaScript 程序修改页面的内容, 结构或样式.
虽然与源 HTML 文档的其他形式类似, DOM 在许多方面是不同的:
它总是有效的 HTML
它是一个活生生的模型, 可以由 JavaScript 修改
它不包含伪元素 (例如,::after)
它确实包含隐藏元素 (例如, display: none)
这里推荐一下我的学习交流群: 731771211, 里面都是学习前端的, 如果你想制作酷炫的网页, 想学习编程. 从最基础的 HTML+CSS+JS[炫酷特效, 游戏, 插件封装, 设计模式] 到移动端 HTML5 的项目实战的学习资料都有整理, 送给每一位前端小伙伴, 有想学习 Web 前端的, 或是转行, 或是大学生, 还有工作中想提升自己能力的, 正在学习的小伙伴欢迎加入
点击: 加入 http://u6.gg/ek2NA
来源: http://www.qdfuns.com/article/51714/8aa1abc3309bcc51604d414e4d31de84.html