# Load 事件 vs DOMContentLoaded 事件 > Difference between document load event and document DOMContentLoaded event? :::info :star: Load 事件註冊在window物件上,它在網頁「所有」資源載入完畢後才觸發。 :star: DOMContentLoaded 事件在整個document(html)完全讀取和解析後就會被觸發,不需等待網頁資源讀取完成。 (網頁資源:stylesheets, images, subframes等等) ::: **當打開一個網頁,DOMContentLoaded 和 Load 事件的觸發時機如下:** > 1. 解析HTML結構。 > 2. 開始加載外部 stylesheets 和 script 。 > 3. 解析並執行 code。 > 4. DOM 樹構建完成。 // :one: DOMContentLoaded 事件被觸發 > 5. 加載完成圖片等外部文件。 > 6. 頁面加載完畢。// :two: Load 事件被觸發 > [color=#f24] *更詳細的示意圖,可以參考:*  ## ex. 在head標籤裡怎麼讀取 script 的內容? ```javascript= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script> document.getElementById('hello').textContent = 'Good Morning!' </script> </head> <body> <div id="hello"></div> </body> </html> ``` :arrow_up: 因為還沒有解析到網頁本體(Document尚未載入),選取不到 DOM **==解決方法:使用 DOMContentLoaded 事件==** DOMContentLoaded 事件發生在 document 上。 使用 addEventListener 來捕獲它: ```javascript= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script> document.addEventListener('DOMContentLoaded', function(){ document.getElementById('hello').textContent = 'Good Morning!' }, false) </script> </head> <body> <div id="hello"></div> </body> </html> ``` ## ex. 圖片大小? ``` JavaScript= <body> <img id="img" src="https://media.makeameme.org/created/yes-keep-going.jpg"> <script> function ready() { alert('DOM is ready'); alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`); } document.addEventListener("DOMContentLoaded", ready); </script> </body> ``` *image因為還沒有載入,所以圖片大小會是 0x0* **==使用 load 事件==** 當整個頁面,包括樣式、圖片和其他資源被載入完成時,會觸發 window 上的 load 事件。可以通過 onload 屬性獲取此事件 ``` JavaScript= <img id="img" src="https://media.makeameme.org/created/yes-keep-going.jpg"> <script> window.addEventListener('load', (event) => { alert('Page loaded'); // 這時圖片已載入 alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`); }); </script> ``` 就能印出圖片大小 ## ex. DOMContentLoaded 和 script :::warning 當瀏覽器處理一個 HTML 文檔,並在文檔中遇到 script 標籤時,就會在繼續構建 DOM 之前運行它。這是一種防範措施,因為 script 可能想要修改 DOM,甚至對其執行 document.write 操作,所以 DOMContentLoaded 必須等待 script 執行結束。 ::: 因此,DOMContentLoaded 肯定在下面的這些 script 執行結束之後發生: ``` JavaScript= <script> document.addEventListener("DOMContentLoaded", () => { alert("DOM ready!"); }); </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js"></script> <script> alert("Library loaded, inline script executed"); </script> ``` 在上面這個例子中,我們首先會看到 “Library loaded…”,然後才會看到 “DOM ready!”(所有script都已經執行結束)。 **例外(暫不討論):** 具有 async 特性(attribute)的 script 不會阻擋 DOMContentLoaded。 使用 document.createElement('script') 動態生成並添加到網頁的 script 也不會阻塞 DOMContentLoaded。 --- 更多參考資料 [測試 DOMContentLoaded 和 Load](http://web.archive.org/web/20150405114023/http://ie.microsoft.com/testdrive/HTML5/DOMContentLoaded/Default.html) [Window: DOMContentLoaded event](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event) [Window: load event](https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event) [页面生命周期:DOMContentLoaded,load,beforeunload,unload](https://zh.javascript.info/onload-ondomcontentloaded)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up