關于最后的立即執行函數和d.onreadystatechange=function(){}不知這樣理解是否有錯?
這是我的理解,請大神來指正,否則我真的不知道該怎么理解這些代碼了。(前邊一些代碼略去)首先開始立即執行函數,在這個立即執行函數里是DOM樹創建完成的判斷(它和window.onload有很大區別,前者是創建DOM樹,onload是不僅樹可能創建完了,還有可能正在加載外部信息),如果DOM樹創建完成跳過try catch執行init()也就是css樣式設置為紅色,如果沒有創建完畢,則執行try中的doSCroll捕獲錯誤并執行catch中的setTimeout,接著利用return跳過該立即執行函數,接下來瀏覽器繼續加載,而代碼執行到d.onreadystatechange=function(){}進行監聽,這種情況下假設30ms進入立即執行函數而48msDOM樹建立完畢,還差18msDOM樹才能建好,于是執行了Timesetout并跳出了立即執行函數,再假設49ms網頁加載完畢,而剛好進入d.onreadystatechange=function(){}的時間是49ms,即dom樹建立完畢網頁加載完畢;由于49ms<Settimeout中的50ms因而執行了d.onreadystatechange=function(){}中的init函數,于是這是在網頁加載完畢的前提下將CSS設置為紅色。情況二:我們依舊假設48msDOM樹建立完畢,但是網頁加載完是51ms,進入立即執行函數的時間是30ms此時30ms<48ms<50ms這意味DOM樹沒有建立,繼續進入到d.onreadystatechange=function(){}時間為48ms,由于網頁未加載完,但時間已經走入到了50ms開始執行setTimeout這個遞歸,此時50ms>48ms(另一邊網頁加載也在進行)DOM樹已經建立完畢,這時執行立即調用函數里的init(),而后網頁加載完成了。
也就是說2個init()分別對應DOM樹建立好了,而網頁不一定加載完的情況下調用init(),和網頁以及DOM樹都加載好了后調用init()函數這2種大情況?
閑話太多,望大神給個評價我的理解方式是否正確?
2016-10-30
1,onload事件不是有可能正在加載外部信息,而是必須等外部數據全部加載完才能觸發。
2,return是用來跳出setTimeout所創建的遞歸函數的外層,在外層阻止運行init(),但是當這個遞歸執行到調用doScroll不拋出錯誤的時候(也就是DOMReady的時候)就沒有return了,此時會執行一次init()。而不是題住理解的return直接跳過了一次性函數去執行后面的readystatechang事件監聽。因此,只要順利,這個一次性函數里的init()是一定會被調用一次的。而且實際應用中setTimeout的第二次參數是0(瀏覽器最短時間內重復執行)而不是50。
3,d.onreadystatechange=function(){}是綁定事件處理函數,這個綁定過程是在函數編譯的時候就完成的,至于觸發這個事件,則是document.readyState發生變化時觸發,因此題主的表述是有點問題的,當readyState為"complete"時,這個事件監聽函數里的init()也是一定會被調用一次的。
綜合2和3,確實是在比兩個邏輯誰快,但理論上肯定是2的邏輯更快,至于為什么要有3,我印象中是為了應付沒有實現DOMContentLoaded也沒有document.documentElement.doScroll在DOM沒準備好時會報錯的特性(這個特性只有低版本的IE有)的非IE瀏覽器準備的。
以上是我的理解,歡迎指正~
2016-10-30
上面的表述有點語病,重新整理了一下,去掉了題主問題中本身表述有誤的部分。
1,return是用來跳出setTimeout所創建的遞歸函數的外層,在外層阻止運行init(),但是當這個遞歸執行到調用doScroll不拋出錯誤的時候(也就是DOMReady的時候)就沒有return了,此時會執行一次init()。因此,只要順利,這個一次性函數里的init()是一定會被調用一次的。而且實際應用中setTimeout的第二次參數是0(瀏覽器最短時間內重復執行)而不是50。
2,d.onreadystatechange=function(){}是綁定事件處理函數,這個綁定過程是在函數編譯的時候就完成的,運行過程中document.readyState發生變化時會觸發事件來運行調用監聽函數,當readyState為"complete"時,這個事件監聽函數里的init()也是一定會被調用一次的。
綜合1和2,有點像是在比誰更快,但理論上肯定是1的更快,至于為什么要有2,我印象中是為了應付沒有實現DOMContentLoaded也沒有document.documentElement.doScroll在DOM沒準備好時會報錯的特性(這個特性只有低版本的IE有)的非IE瀏覽器的,而不是兩個邏輯代碼都是為低版本IE準備的。