理解DOM到底是什麼

Ioodu發表於2019-03-04

文件物件模型或者說我們熟悉的“DOM”,web網頁的一個介面。它本質上是允許程式讀取和操作頁面的內容,結構和樣式的頁面API。 接下來一一分解。

網頁如何構建

瀏覽器如何從源HTML文件轉到在視口中顯示樣式化和互動式頁面稱為“關鍵渲染路徑”。 這些步驟大致可分為兩個階段。第一階段涉及瀏覽器解析文件以確定最終將在頁面上渲染的內容,第二階段涉及瀏覽器執行渲染。

理解DOM到底是什麼
第一階段的結果是所謂的“渲染樹”。 渲染樹是將在頁面上呈現的HTML元素及其相關樣式的表示。 為了構建這個樹,瀏覽器需要兩件事:

  1. CSSOM,元素相關樣式的結構;
  2. DOM,元素結構

DOM如何建立(長啥樣)

DOM是HTML源文件的基於物件的表示。它有一些差異,我們將在下面看到,但它本質上是一種嘗試將HTML文件的結構和內容轉換為可供各種程式使用的物件模型。

DOM的物件結構由所謂的“節點樹”表示。 它之所以被稱為樹是因為它可以被認為是具有單個父莖的樹,其分枝成幾個子枝,每個子枝可以具有葉子。 在這種情況下,父“stem”是根元素,子“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>
複製程式碼

該文件缺少和元素,這是有效HTML的要求。 如果我們檢視生成的DOM樹,我們將看到這已得到糾正:

html
    head
    body
        Hello, world!
複製程式碼

2. 當JavaScript修改了DOM

除了作為檢視HTML文件內容的介面之外,還可以修改DOM,使其成為動態資源。

例如,我們可以使用Javascript為DOM建立其他節點。

const newParagraph = document.createElement("p");
const paragraphContent = document.createTextNode("I'm new!");
newParagraph.appendChild(paragraphContent);
document.body.appendChild(newParagraph);
複製程式碼

如上會更改我們的DOM,但並不是更改了我們的HTML文件。

DOM不是你在瀏覽器中看到的(即渲染樹)

你在瀏覽器視口中看到的是渲染樹,正如我所提到的,它是DOM和CSSOM的組合。 真正將DOM與渲染樹分開的是,後者只包含最終將在螢幕上繪製的內容。

因為渲染樹僅關注渲染的內容,所以它會排除視覺上隱藏的元素。 例如,具有顯示的元素:沒有與之關聯的樣式。

<!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?
複製程式碼

但是,渲染樹,即我們在視口上所見,不包含這個p元素

html
    body
        h1
            Hello, world!
複製程式碼

DOM不是DevTools中的結構

這種差異有點小,因為DevTools元素檢查器提供了我們在瀏覽器中最接近的DOM。 但是,DevTools檢查器包含不在DOM中的其他資訊。

最好的例子是CSS偽元素。 使用:: before和:: after選擇器建立的偽元素構成CSSOM和渲染樹的一部分,但在技術上不是DOM的一部分。 這是因為DOM僅由源HTML文件構建,不包括應用於元素的樣式。

儘管偽元素不是DOM的一部分,但它們仍在我們的devtools元素檢查器中。

理解DOM到底是什麼
這就是為什麼偽元素不能被Javascript直接獲取到的原因,因為偽元素不是DOM的一部分。

總結

DOM是HTML文件的介面。 它被瀏覽器用作確定在視口中呈現內容的第一步,並通過Javascript程式來修改頁面的內容,結構或樣式。

雖然與其他形式的源HTML文件類似,但DOM在許多方面有所不同:

  1. 它總是有效的HTML
  2. 它是一個可以通過Javascript修改的結構
  3. 它不包含偽元素(例如:: after)
  4. 它確實包含隱藏元素(例如display:none

相關文章