理解DOM究竟是什麼

文檔對象模型或者說咱們熟悉的「DOM」,web網頁的一個界面。它本質上是容許程序讀取和操做頁面的內容,結構和樣式的頁面API。 接下來一一分解。javascript

網頁如何構建

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

第一階段的結果是所謂的「渲染樹」。 渲染樹是將在頁面上呈現的HTML元素及其相關樣式的表示。 爲了構建這個樹,瀏覽器須要兩件事:

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

DOM如何建立(長啥樣)

DOM是HTML源文檔的基於對象的表示。它有一些差別,咱們將在下面看到,但它本質上是一種嘗試將HTML文檔的結構和內容轉換爲可供各類程序使用的對象模型。java

DOM的對象結構由所謂的「節點樹」表示。 它之因此被稱爲樹是由於它能夠被認爲是具備單個父莖的樹,其分枝成幾個子枝,每一個子枝能夠具備葉子。 在這種狀況下,父「stem」是根元素,子「branches」是嵌套元素,「leaves」是元素中的內容。web

咱們以此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>
複製代碼

此文檔能夠表示爲如下節點樹:app

html
    head
        title
            My first web page
    body
        h1
            Hello, world!
        p
            How are you?
複製代碼

DOM不是什麼

在上面給出的示例中,看起來DOM是源HTML文檔的一對一映射或者你看到的DevTools的映射。 可是,正如我所提到的,存在差別。爲了徹底理解DOM是什麼,咱們須要看看它不是什麼。ui

DOM不是你的html源文檔

儘管DOM是從源HTML文檔建立的,但它並不老是徹底相同。 有兩個實例,DOM能夠與源HTML不一樣。spa

1. 當HTML無效時

DOM是有效HTML文檔的接口。 在建立DOM的過程當中,瀏覽器能夠糾正HTML代碼中的一些無效。3d

咱們以此HTML文檔爲例:code

<!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元素檢查器中。

這就是爲何僞元素不能被Javascript直接獲取到的緣由,由於僞元素不是DOM的一部分。

總結

DOM是HTML文檔的接口。 它被瀏覽器用做肯定在視口中呈現內容的第一步,並經過Javascript程序來修改頁面的內容,結構或樣式。

雖然與其餘形式的源HTML文檔相似,但DOM在許多方面有所不一樣:

  1. 它老是有效的HTML
  2. 它是一個能夠經過Javascript修改的結構
  3. 它不包含僞元素(例如:: after)
  4. 它確實包含隱藏元素(例如display:none
相關文章
相關標籤/搜索