請說明 DOMContentLoaded, load, beforeunload, unload 的觸發時機
2024年7月15日
我們都知道,網頁是瀏覽器載入、解析 HTML 而生。 瀏覽器在解析完 HTML 後會建構出我們熟悉的 DOM 樹,而透過 DOM 樹,開發者就能容易地透過 JavaScript 去操作 DOM 節點,讓網頁不只是能看,而是能夠互動。而網頁與 DOM 也有我們熟知的生命週期,例如很常聽到的 DOMContentLoaded
,以及面試中常會被問到的「DOMContentLoaded
與 load
事件有什麼不同?」
這篇文會以第一人稱的形式,來模擬回答 DOM 生命週期常見的問題。我們就先從「DOMContentLoaded
與 load
事件有什麼不同?」這題開始吧!
DOMContentLoaded
與 load
事件有什麼不同?
DOMContentLoaded
是當 DOM 建構完成後會觸發的事件,因此只要當 HTML 文件完全載入、解析完後就會出發。這個時候 CSS 的樣式表、圖片等可能還沒完全載入。因為很多 JavaScript 腳本,需要等到 DOM 節點被完整建立出來後,才能夠使用,不然沒有 DOM 節點,就沒辦法去做操作;所以 DOMContentLoaded
可以幫助開發者偵測什麼時候可以執行這些 JavaScript 腳本。
load
(window.onload
) 這個事件,則是在 HTML 文件完全載入、解析,以及 CSS 樣式表、圖片等各類資源都載入好後,才會被觸發。所以可以理解成網頁完整載入,才會觸發 load
事件。也因此,load
會是在 DOMContentLoaded
之後被觸發。如果 JavaScript 的邏輯會去改動到樣式、圖片等,就會更適合用 load
而非 DOMContentLoaded
幫助我們偵測。
我們也可以從另一個角度理解 DOMContentLoaded
與 load
事件的不同。在 document
物件有個 readyState
的屬性 詳見此 MDN,它有三個值一個是 loading
這代表 HTML 文件正在被解析中;第二個是 interactive
這代表 HTML 文件已經完成讀取和解析,而 DOMContentLoaded 已經被觸發,所以已經可以有互動了;最後則是 complete
,當進到這狀態時,就會觸發 load
事件。
beforeunload
與 unload
的觸發時機與作用分別為何?
DOMContentLoaded
與 load
事件是在偵測 DOM 與網頁的建置完成,是在生命週期的開始;而 beforeunload
與 unload
則是在偵測聲明週期的結尾,意即在網頁要被關閉時觸發。
beforeunload
(window.onbeforeunload
) 是在使用者要離開網頁前會被觸發,例如要去別頁、關閉分頁等等的狀況時,會觸發這個事件。它的用途是可以讓開發者在使用者要離開前,能夠做點什麼。常見的使用情境,是使用者要離開網頁前,會跳出一個彈跳視窗,詢問使用者是不是真的要離開或關閉網頁,這就是透過 beforeunload
的事件觸發,來得知應該要跳出這個視窗。
至於 unload
(window.onunload
) 則是在離開或關閉網頁後,才會被觸發;所以它的觸發時機是在 beforeunload
之後。如果我們要有彈跳視窗,不能用 unload
因為會太晚,我們會需要 beforeunload
。而 unload
的用途通常會是用來埋資料分析,因為是在使用者離開網頁時觸發,我們就可以得知使用者確切是在什麼時機離開了網頁。