到底是什么DOM?, What, exactly, is the DOM?, 什么是 HTML DOM?

 

文档对象模型或“ DOM”是网页的接口。它本质上是页面的API,允许程序读取和操纵页面的内容,结构和样式。让我们分解一下。

 

网页是如何构建的?

浏览器如何从源HTML文档转换为在视口中显示样式化的交互式页面的方式称为“关键渲染路径”。尽管此过程可以分为几个步骤,但是正如我在“了解关键渲染路径”一文中所介绍的那样,这些步骤可以大致分为两个阶段。第一阶段涉及浏览器解析文档以确定最终将在页面上呈现的内容,第二阶段涉及浏览器执行呈现。

到底是什么DOM?, What, exactly, is the DOM?, 什么是 HTML DOM?
到底是什么DOM?, What, exactly, is the DOM?, 什么是 HTML DOM?

第一阶段的结果就是所谓的“渲染树”。渲染树表示将在页面上渲染的HTML元素及其相关样式。为了构建此树,浏览器需要两件事:

  1. CSSOM,表示与元素关联的样式
  2. DOM,元素的表示

 

DOM是如何创建的(及其外观如何)?

DOM是源HTML文档的基于对象的表示形式。正如我们将在下面看到的那样,它具有一些差异,但是本质上是将HTML文档的结构和内容转换为可以由各种程序使用的对象模型的尝试。

DOM的对象结构由所谓的“节点树”表示。之所以这样称呼它,是因为它可以被认为是一棵带有单个父茎的树,该母茎分支成几个子枝,每个子枝都可能有叶子。在这种情况下,父级“ stem”是根<html>元素,子级“ branches”是嵌套元素,而“ leaves”是元素内的内容。

 

让我们以这个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>

 

该文档可以表示为以下节点树:

  • html
    • head
      • title
        • My first web page
    • body
      • h1
        • Hello, world!
      • p
        • How are you?

 

DOM不是什么

在我上面给出的示例中,DOM似乎是源HTML文档或您看到的DevTools的一对一映射。但是,正如我所提到的,存在差异。为了完全理解DOM什么,我们需要看一下它不是什么。

 

DOM不是您的源HTML

尽管DOM是从源HTML文档创建的,但它并不总是完全相同的。在两种情况下,DOM可能与源HTML不同。

 

1. HTML无效时

DOM是有效HTML文档的接口。在创建DOM的过程中,浏览器可能会更正HTML代码中的某些无效内容。

让我们以这个HTML文档为例:

<!doctype html>
<html>
Hello, world!
</html>

 

该文档缺少<head>and<body>元素,这是有效HTML的要求。如果查看生成的DOM树,我们将看到已被更正:

html

  • head
  • body
    • Hello, world!

 

2.当使用Javascript修改DOM时

除了作为查看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与渲染树区分开的是,后者仅由最终将在屏幕上绘制的内容组成。

因为渲染树仅与渲染的内容有关,所以它排除了视觉上隐藏的元素。例如,具有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>元素:

html

  • head
  • body
    • h1
      • Hello, world!
    • p
      • How are you?

 

但是,渲染树以及因此在视口中看到的树将不包含该元素。

html

  • body
    • h1
      • Hello, world!

 

DOM不是DevTools中的内容

这种差异要小得多,因为DevTools元素检查器提供了与浏览器中的DOM最接近的近似值。但是,DevTools检查器包含DOM中没有的其他信息。

最好的例子是CSS伪元素。使用::before::after选择器创建的伪元素构成CSSOM和渲染树的一部分,但从技术上讲不是DOM的一部分。这是因为DOM仅从源HTML文档构建,不包括应用于元素的样式。

尽管伪元素不是DOM的一部分,但它们在我们的devtools元素检查器中。

到底是什么DOM?, What, exactly, is the DOM?, 什么是 HTML DOM?
到底是什么DOM?, What, exactly, is the DOM?, 什么是 HTML DOM?

这就是为什么伪元素不能被Javascript定位的原因,因为它们不是DOM的一部分。

 

回顾

DOM是HTML文档的接口。浏览器将其用作确定在视口中呈现内容的第一步,而Javascript程序将其用于修改页面的内容,结构或样式。

尽管与源HTML文档的其他形式相似,但DOM在许多方面有所不同:

  • 它始终是有效的HTML
  • 这是一个可以通过Javascript修改的活动模型
  • 它不包含伪元素(例如::after
  • 它确实包含隐藏的元素(例如,带有display: none

 

 

本文:到底是什么DOM?, What, exactly, is the DOM?, 什么是 HTML DOM?

One Comment

Leave a Reply