成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

頁面生命周期:DOMContentLoaded, load, beforeunload, unloa

lx1036 / 702人閱讀

摘要:所以有可能在所有腳本執(zhí)行完畢后觸發(fā)。如果用戶即將離開頁面或者關(guān)閉窗口時,事件將會被觸發(fā)以進(jìn)行額外的確認(rèn)。狀態(tài)表示事件即將被觸發(fā)??偨Y(jié)頁面事件的生命周期事件在樹構(gòu)建完畢后被觸發(fā),我們可以在這個階段使用去訪問元素。

頁面生命周期:DOMContentLoaded, load, beforeunload, unload

原文地址:http://javascript.info/onload...

HTML頁面的生命周期有以下三個重要事件:

DOMContentLoaded — 瀏覽器已經(jīng)完全加載了HTML,DOM樹已經(jīng)構(gòu)建完畢,但是像是 和樣式表等外部資源可能并沒有下載完畢。

load — 瀏覽器已經(jīng)加載了所有的資源(圖像,樣式表等)。

beforeunload/unload -- 當(dāng)用戶離開頁面的時候觸發(fā)。

每個事件都有特定的用途

DOMContentLoaded -- DOM加載完畢,所以js可以訪問所有DOM節(jié)點,初始化界面。

load -- 附加資源已經(jīng)加載完畢,可以在此事件觸發(fā)時獲得圖像的大?。ㄈ绻麤]有被在HTML/CSS中指定)

beforeunload/unload -- 用戶正在離開頁面:可以詢問用戶是否保存了更改以及是否確定要離開頁面。

來看一下每個事件的細(xì)節(jié)。

DOMContentLoaded

DOMContentLoadeddocument 對象觸發(fā)。

我們使用 addEventListener 來監(jiān)聽它:

document.addEventListener("DOMContentLoaded", ready);

舉個例子



在這個例子中 DOMContentLoaded在document加載完成后就被觸發(fā),無需等待其他資源的載入,所以alert輸出的圖像的大小為0。

這么看來DOMContentLoaded 似乎很簡單,DOM樹構(gòu)建完畢之后就運行該事件,不過其實存在一些陷阱。

DOMContentLoaded 和腳本

當(dāng)瀏覽器在解析HTML頁面時遇到了 標(biāo)簽,將無法繼續(xù)構(gòu)建DOM樹(譯注:UI渲染線程與JS引擎是互斥的,當(dāng)JS引擎執(zhí)行時UI線程會被掛起),必須立即執(zhí)行腳本。所以 DOMContentLoaded 有可能在所有腳本執(zhí)行完畢后觸發(fā)。

外部腳本(帶src的)的加載和解析也會暫停DOM樹構(gòu)建,所以 DOMContentLoaded 也會等待外部腳本。

不過有兩個例外是帶asyncdefer的外部腳本,他們告訴瀏覽器繼續(xù)解析而不需要等待腳本的執(zhí)行,所以用戶可以在腳本加載完成前可以看到頁面,有較好的用戶體驗。

asyncdefer屬性僅僅對外部腳本起作用,并且他們在src不存在時會被自動忽略。

它們都告訴瀏覽器繼續(xù)處理頁面上的內(nèi)容,而在后臺加載腳本,然后在腳本加載完畢后再執(zhí)行。所以腳本不會阻塞DOM樹的構(gòu)建和頁面的渲染。

(譯注:其實這里是不對的,帶有asyncdefer的腳本的下載是和HTML的下載與解析是異步的,但是js的執(zhí)行一定是和UI線程是互斥的,像下面這張圖所示,async在下載完畢后的執(zhí)行會阻塞HTML的解析)

他們有兩處不同:

async defer
順序 帶有async的腳本是優(yōu)先執(zhí)行先加載完的腳本,他們在頁面中的順序并不影響他們執(zhí)行的順序。 帶有defer的腳本按照他們在頁面中出現(xiàn)的順序依次執(zhí)行。
DOMContentLoaded 帶有async的腳本也許會在頁面沒有完全下載完之前就加載,這種情況會在腳本很小或本緩存,并且頁面很大的情況下發(fā)生。 帶有defer的腳本會在頁面加載和解析完畢后執(zhí)行,剛好在 DOMContentLoaded之前執(zhí)行。

所以async用在那些完全不依賴其他腳本的腳本上。

### DOMContentLoaded and styles

External style sheets don"t affect DOM, and so `DOMContentLoaded` does not wait for them.
外部樣式表并不會影響DOM,所以`DOMContentLoaded`并不會被他們阻塞。
But there"s a pitfall: if we have a script after the style, then that script must wait for the stylesheet to execute:
不過仍然有一個陷阱:如果在樣式后面有一個內(nèi)聯(lián)腳本,那么腳本必須等待樣式先加載完。


發(fā)生這種事的原因是腳本也許會像上面的例子中所示,去得到一些元素的坐標(biāo)或者基于樣式的屬性。所以他們自然要等到樣式加載完畢才可以執(zhí)行。

DOMContentLoaded需要等待腳本的執(zhí)行,腳本又需要等待樣式的加載。

瀏覽器的自動補(bǔ)全

Firefox, Chrome和Opera會在DOMContentLoaded執(zhí)行時自動補(bǔ)全表單。

例如,如果頁面有登錄的界面,瀏覽器記住了該頁面的用戶名和密碼,那么在 DOMContentLoaded運行的時候瀏覽器會試圖自動補(bǔ)全表單(如果用戶設(shè)置允許)。

所以如果DOMContentLoaded被一個需要長時間執(zhí)行的腳本阻塞,那么自動補(bǔ)全也會等待。你也許見過某些網(wǎng)站(如果你的瀏覽器開啟了自動補(bǔ)全)—— 瀏覽器并不會立刻補(bǔ)全登錄項,而是等到整個頁面加載完畢后才填充。這就是因為在等待DOMContentLoaded事件。

使用帶asyncdefer的腳本的一個好處就是,他們不會阻塞DOMContentLoaded和瀏覽器自動補(bǔ)全。(譯注:其實執(zhí)行還是會阻塞的)

window.onload

window對象上的onload事件在所有文件包括樣式表,圖片和其他資源下載完畢后觸發(fā)。

下面的例子正確檢測了圖片的大小,因為window.onload會等待所有圖片的加載。



window.onunload

用戶離開頁面的時候,window對象上的unload事件會被觸發(fā),我們可以做一些不存在延遲的事情,比如關(guān)閉彈出的窗口,可是我們無法阻止用戶轉(zhuǎn)移到另一個頁面上。

所以我們需要使用另一個事件 — onbeforeunload。

window.onbeforeunload

如果用戶即將離開頁面或者關(guān)閉窗口時,beforeunload事件將會被觸發(fā)以進(jìn)行額外的確認(rèn)。

瀏覽器將顯示返回的字符串,舉個例子:

window.onbeforeunload = function() {
  return "There are unsaved changes. Leave now?";
};

有些瀏覽器像Chrome和火狐會忽略返回的字符串取而代之顯示瀏覽器自身的文本,這是為了安全考慮,來保證用戶不受到錯誤信息的誤導(dǎo)。

readyState

如果我們在整個頁面加載完畢后設(shè)置DOMContentLoaded會發(fā)生什么呢?

啥也沒有,DOMContentLoaded不會被觸發(fā)。

有一些情況我們無法確定頁面上是否已經(jīng)加載完畢,比如一個帶有async的外部腳本的加載和執(zhí)行是異步的(注:執(zhí)行并不是異步的-_-)。在不同的網(wǎng)絡(luò)狀況下,腳本有可能是在頁面加載完畢后執(zhí)行也有可能是在頁面加載完畢前執(zhí)行,我們無法確定。所以我們需要知道頁面加載的狀況。

document.readyState屬性給了我們加載的信息,有三個可能的值:

loading 加載 - document仍在加載。

interactive 互動 - 文檔已經(jīng)完成加載,文檔已被解析,但是諸如圖像,樣式表和框架之類的子資源仍在加載。

complete - 文檔和所有子資源已完成加載。狀態(tài)表示 load 事件即將被觸發(fā)。

所以我們可以檢查 document.readyState 的狀態(tài),如果沒有就緒可以選擇掛載事件,如果已經(jīng)就緒了就可以直接立即執(zhí)行。

像這樣:

function work() { /*...*/ }

if (document.readyState == "loading") {
  document.addEventListener("DOMContentLoaded", work);
} else {
  work();
}

每當(dāng)文檔的加載狀態(tài)改變的時候就有一個readystatechange事件被觸發(fā),所以我們可以打印所有的狀態(tài)。

// current state
console.log(document.readyState);

// print state changes
document.addEventListener("readystatechange", () => console.log(document.readyState));

readystatechange 是追蹤頁面加載的一個可選的方法,很早之前就已經(jīng)出現(xiàn)了。不過現(xiàn)在很少被使用了,為了保持完整性還是介紹一下它。

readystatechange的在各個事件中的執(zhí)行順序又是如何呢?






輸出如下:

[1] initial readyState:loading

[2] readyState:interactive

[2] DOMContentLoaded

[3] iframe onload

[4] readyState:complete

[4] img onload

[4] window onload

方括號中的數(shù)字表示他們發(fā)生的時間,真實的發(fā)生時間會更晚一點,不過相同數(shù)字的時間可以認(rèn)為是在同一時刻被按順序觸發(fā)(誤差在幾毫秒之內(nèi))

document.readyStateDOMContentLoaded前一刻變?yōu)?b>interactive,這兩個事件可以認(rèn)為是同時發(fā)生。

document.readyState 在所有資源加載完畢后(包括iframeimg)變成complete,我們可以看到complete、 img.onloadwindow.onload幾乎同時發(fā)生,區(qū)別就是window.onload在所有其他的load事件之后執(zhí)行。

總結(jié)

頁面事件的生命周期:

DOMContentLoaded事件在DOM樹構(gòu)建完畢后被觸發(fā),我們可以在這個階段使用js去訪問元素。

asyncdefer的腳本可能還沒有執(zhí)行。

圖片及其他資源文件可能還在下載中。

load事件在頁面所有資源被加載完畢后觸發(fā),通常我們不會用到這個事件,因為我們不需要等那么久。

beforeunload在用戶即將離開頁面時觸發(fā),它返回一個字符串,瀏覽器會向用戶展示并詢問這個字符串以確定是否離開。

unload在用戶已經(jīng)離開時觸發(fā),我們在這個階段僅可以做一些沒有延遲的操作,由于種種限制,很少被使用。

document.readyState表征頁面的加載狀態(tài),可以在readystatechange中追蹤頁面的變化狀態(tài):

loading — 頁面正在加載中。

interactive -- 頁面解析完畢,時間上和 DOMContentLoaded同時發(fā)生,不過順序在它之前。

complete -- 頁面上的資源都已加載完畢,時間上和window.onload同時發(fā)生,不過順序在他之前。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/51340.html

相關(guān)文章

  • 頁面生命周期DOMContentLoaded, load, beforeunload, unloa

    摘要:所以有可能在所有腳本執(zhí)行完畢后觸發(fā)。如果用戶即將離開頁面或者關(guān)閉窗口時,事件將會被觸發(fā)以進(jìn)行額外的確認(rèn)。狀態(tài)表示事件即將被觸發(fā)??偨Y(jié)頁面事件的生命周期事件在樹構(gòu)建完畢后被觸發(fā),我們可以在這個階段使用去訪問元素。 頁面生命周期:DOMContentLoaded, load, beforeunload, unload 原文地址:http://javascript.info/onload.....

    luckyyulin 評論0 收藏0
  • WEB頁面生命周期,DOMContentLoaded,load,beforeunload,unlo

    摘要:簡言理解頁面的生命周期,文檔加載事件及順序?qū)﹂_發(fā)有十分的重要意義。同步的腳本最先執(zhí)行,它先于事件執(zhí)行。當(dāng)準(zhǔn)備就緒時,事件在上觸發(fā)。表示文檔的當(dāng)前狀態(tài),可以在事件中跟蹤文檔狀態(tài)的變更。已經(jīng)解析完畢時觸發(fā),幾乎與同時發(fā)生,但在事件之前觸發(fā)。 簡言 理解WEB頁面的生命周期,文檔加載事件及順序?qū)EB開發(fā)有十分的重要意義。如果不理解,在元素未加載就提前操作元素,則得不到想要的結(jié)果。而如果頁面...

    Jingbin_ 評論0 收藏0
  • DOMContentLoadedload的區(qū)別

    摘要:所以所需要的時間必然大于等于所需要的時間。頁面的生命周期主要有三個重要的事件,已經(jīng)構(gòu)建好,可以對節(jié)點進(jìn)行操作,所有資源加載完畢,可以對資源進(jìn)行一系列操作,比如獲取圖片寬高等基本不會用到,當(dāng)瀏覽器窗口關(guān)閉或者刷新時,會觸發(fā)事件。 DOMContentLoaded與load的區(qū)別 showImg(https://segmentfault.com/img/remote/14600000192...

    niuxiaowei111 評論0 收藏0
  • JS魔法堂:定義頁面的Dispose方法——[before]unload事件啟示錄

    摘要:坑無視和是十分特殊的事件,要求事件處理函數(shù)內(nèi)部不能阻塞當(dāng)前線程,而卻恰恰就會阻塞當(dāng)前線程,因此規(guī)范中以明確在和中直接無視這幾個方法的調(diào)用。 前言 ?最近實施的同事報障,說用戶審批流程后直接關(guān)閉瀏覽器,操作十余次后系統(tǒng)就報用戶會話數(shù)超過上限,咨詢4A同事后得知登陸后需要顯式調(diào)用登出API才能清理4A端,否則必然會超出會話上限。?即使在頁面上增添一個登出按鈕也無法保證用戶不會直接關(guān)掉瀏覽器...

    Chiclaim 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<