視覺化講解DOM構建過程

ssthouse發表於2018-07-16

前言

最近在看 _Secrets of the JavaScript Ninja_, 書中第二章講到 DOM 的構建流程.

記得我之前也為理解 DOM 構建流程查閱過數次資料, 雖然每次查閱完都覺得 DOM 構建流程很簡單, 看完便懂, 但是懂了又忘還是讓人有些頭疼.

為了給自己加深印象, 也為了為大家提供一個視覺化的理解 DOM 構建過程的方式, 筆者製作了一個簡單的網頁來動態演示 DOM 構建過程. 希望能給大家帶來一些幫助.

效果

線上檢視

線上 demo (請使用 pc 訪問)

前進, 後退

網頁展示了一個簡單的 HTML 頁面的 DOM 渲染過程. 使用者點選前進,後退按鈕時, 頁面左側會顯示出當前的 HTML 程式碼, 右側則會顯示出實時的 DOM 結構圖:

forward and backword

自動播放

點選 Auto Play 按鈕, 頁面會自動播放頁面的整個構建過程:

auto play

DOM 構建過程

DOM 元素的作用 & 基本構建過程:

這裡直接引用一下原文:

The goal of this page-building phase is to set up the UI of a web application, and this is done in two distinct steps:
1 Parsing the HTML and building the Document Object Model (DOM)
2 Executing JavaScript code
Step 1 is performed when the browser is processing HTML nodes, and step 2 is > performed whenever a special type of HTML element—the script element (that > contains or
refers to JavaScript code)—is encountered. During the page-building phase, the browser
can switch between these two steps as many times as necessary.

瀏覽器 頁面構建 步驟的目的是為 UI 渲染做準備, 頁面構建是由下面兩部分購成的:

  • 解析 HTML 節點, 並且構建 DOM 元素
  • 執行 JavaScript 程式碼

其中第一步在瀏覽器解析到 HTML 節點時執行, 第二步在解析到 script 標籤時執行. 在頁面構建的過程中, 以上兩步可以無數次的交替執行.

It’s important to emphasize that, although the HTML and the DOM are closely
linked, with the DOM being constructed from HTML, they aren’t one and the same.
You should think of the HTML code as a blueprint the browser follows when > constructing the initial DOM—the UI—of the page. The browser can even fix > problems that it finds with this blueprint in order to create a valid DOM.

需要注意的是, 雖然 HTML 和 DOM 兩者關係緊密(DOM 是由 HTML 檔案構建而來), 但他們並不是相同的. 你應該將 HTML 看作是瀏覽器用來渲染 DOM 元素(頁面 UI) 的藍圖. 瀏覽器甚至可以可以修復這個藍圖(HTML)中的問題, 並構建出有效的 DOM.

下面用視覺化講解中的步驟依次講解:

首先看看我們想要渲染的 HTML 程式碼:

<!DOCTYPE html>
<html>
    <head>
      <title>Web app lifecycle</title>
      <style>
          #list { color: green;}
          #second { color: red;}
      </style>
    </head>
    <body>
        <h1>head one</h1>
        <ul id="list"></ul>
        <script>
            var liElement = document.createElement("li");
            liElement.textContent = `I am a li`;
            document.getElementById(`list`).appendChild(liElement);
        </script>
    </body>
</html>

接下來按照瀏覽器的構建順序來看:

首先瀏覽器遇到下面這段程式碼, 解析出 html 節點作為 DOM 的根節點:

<!DOCTYPE html>
<html>

step 1

接下來是 <head> 標籤, 將其放置在 html 節點下:

step 2

繼續解析, 遇到 <title> 標籤, 因為其是 <head> 的子標籤, 故將其放置在 head 節點下.

step 3

然後是 <style> 標籤, 類似的, 放在 head 節點下:

<style>
    #list { color: green;}
    #second { color: red;}
</style>

step 4

接下來解析到 <body> 標籤, 因其為 <html> 的子標籤, 故將其放置在 html 節點下:

step 5

然後是 <h1> 標籤, 放置在 body 節點下:

step 6

繼續, <ul> 標籤, 同樣的, 放置在 body 節點下:

step 7

接下來, 瀏覽器遇到了 <script> 標籤, 根據前面的知識我們知道, 瀏覽器會停下來並執行<script> 中的程式碼. 所以下面這段程式碼會被立即執行:

<script>
    var liElement = document.createElement("li");
    liElement.textContent = `I am a li`;
    document.getElementById(`list`).appendChild(liElement);
</script>

這段程式碼的邏輯是: 向 idlist 的 DOM 節點新增一個 li 作為子元素, 故執行完成後 DOM 樹會是這樣:

step 7

最後, 瀏覽器會解析到 <body/></html> 等標籤, 結束解析過程. 最終我們得到的 DOM 結構如圖:

step 9

後記

預計我會將 Secrets of the JavaScript Ninja 後續章節中的一些知識點也通過類似的方式進行視覺化.

如果你也有希望能做成視覺化講解的: 知識點, 演算法, 技術原理, 歡迎在下面留言與我交流, 期待大家的反饋 ?

演示頁面用到的技術為: Vue, D3.js, 歡迎 fork & star
Github 地址

想繼續瞭解 D3.js

這裡是我的 D3.js資料視覺化 相關部落格的 github 地址, 歡迎 fork & star :tada:

D3-blog

如果覺得不錯的話, 不妨點選下面的連結關注一下 : )

github 主頁

知乎專欄

掘金


相關文章