請說明 DOMContentLoaded, load, beforeunload, unload 的觸發時機

2022年1月15日

💎 加入 E+ 成長計畫 與超過 400+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

我們都知道,網頁是瀏覽器載入、解析 HTML 而生。 瀏覽器在解析完 HTML 後會建構出我們熟悉的 DOM 樹,而透過 DOM 樹,開發者就能容易地透過 JavaScript 去操作 DOM 節點,讓網頁不只是能看,而是能夠互動。而網頁與 DOM 也有我們熟知的生命週期,例如很常聽到的 DOMContentLoaded ,以及面試中常會被問到的「DOMContentLoadedload 事件有什麼不同?」

這篇文會以第一人稱的形式,來模擬回答 DOM 生命週期常見的問題。我們就先從「DOMContentLoadedload 事件有什麼不同?」這題開始吧!

DOMContentLoadedload 事件有什麼不同?

DOMContentLoaded 是當 DOM 建構完成後會觸發的事件,因此只要當 HTML 文件完全載入、解析完後就會出發。這個時候 CSS 的樣式表、圖片等可能還沒完全載入。因為很多 JavaScript 腳本,需要等到 DOM 節點被完整建立出來後,才能夠使用,不然沒有 DOM 節點,就沒辦法去做操作;所以 DOMContentLoaded 可以幫助開發者偵測什麼時候可以執行這些 JavaScript 腳本。

load (window.onload) 這個事件,則是在 HTML 文件完全載入、解析,以及 CSS 樣式表、圖片等各類資源都載入好後,才會被觸發。所以可以理解成網頁完整載入,才會觸發 load 事件。也因此,load 會是在 DOMContentLoaded 之後被觸發。如果 JavaScript 的邏輯會去改動到樣式、圖片等,就會更適合用 load 而非 DOMContentLoaded 幫助我們偵測。

我們也可以從另一個角度理解 DOMContentLoadedload 事件的不同。在 document 物件有個 readyState 的屬性 (詳見此),它有三個值一個是 loading 這代表 HTML 文件正在被解析中;第二個是 interactive 這代表 HTML 文件已經完成讀取和解析,而 DOMContentLoaded 已經被觸發,所以已經可以有互動了;最後則是 complete ,當進到這狀態時,就會觸發 load 事件。

beforeunloadunload 的觸發時機與作用分別為何?

DOMContentLoadedload 事件是在偵測 DOM 與網頁的建置完成,是在生命週期的開始;而 beforeunloadunload 則是在偵測聲明週期的結尾,意即在網頁要被關閉時觸發。

beforeunload (window.onbeforeunload) 是在使用者要離開網頁前會被觸發,例如要去別頁、關閉分頁等等的狀況時,會觸發這個事件。它的用途是可以讓開發者在使用者要離開前,能夠做點什麼。常見的使用情境,是使用者要離開網頁前,會跳出一個彈跳視窗,詢問使用者是不是真的要離開或關閉網頁,這就是透過 beforeunload 的事件觸發,來得知應該要跳出這個視窗。

至於 unload (window.onunload) 則是在離開或關閉網頁後,才會被觸發;所以它的觸發時機是在 beforeunload 之後。如果我們要有彈跳視窗,不能用 unload 因為會太晚,我們會需要 beforeunload。而 unload 的用途通常會是用來埋資料分析,因為是在使用者離開網頁時觸發,我們就可以得知使用者確切是在什麼時機離開了網頁。

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們