原生js實現jQuery的ready方法

#window.onload

From the MDN, window.onload:

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.

window.onload在頁面的DOM加載完成,所有的圖片、子frame等所有的元素都加載完成的時候纔會觸發。

#$(document).ready

From the jQuery API documentation, .ready( handler ):

While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.

$(document).ready方法發生在DOM樹構造完成,而不會等到其餘的所有的元素都加載完成。其實說白了就是ready方法在onload之前發生,一般發生在DOM樹構造完成的時候。

具體一些,可以從以下幾方面對比$(document).readywindow.onload的區別:

  1. 執行時間
    window.onload必須等到頁面內包括圖片的所有元素加載完畢後才能執行。
    $(document).ready是DOM結構繪製完畢後就執行,不必等到圖片等資源加載完成後才執行。
  2. 編寫個數不同
    window.onload不能同時編寫多個,如果有多個window.onload方法,後面會覆蓋前面,並且只會執行一個onload方法。
    $(document).ready可以同時編寫多個,並且都可以得到執行。
window.onload = function(){
    console.log("window.onload event1");
}
window.onload = function(){
    console.log("window.onload event2");
}
$(document).ready(function(){
    console.log("jquery ready event1");
})
$(document).ready(function(){
    console.log("jquery ready event2");
})

執行結果如下:
jqueryready-windowonload.png

確實可以看出ready先於onload事件。並且onload只能有一個,後面覆蓋前面,而ready恰好相反。

  1. 簡化寫法
    window.onload沒有簡化寫法。
    $(document).ready(function(){})可以簡寫成$(function(){});
    在一些開發中,大多數時候,第一行寫的是:
$(document).ready(function(){
    //coding...
});

這個時候,不一定要等所有的圖片加載完畢,就可以執行一些方法,不過有些時候,必須要等所有的元素都加載完畢,纔可以執行一些方法,比如說,部分圖片或者什麼其他方面還沒有加載好,這個時候,點擊某些按鈕,會導致出現意外的情況,這個時候,就需要用到$(window).load方法:

$(window).load

$(window).loadwindow.onload其實沒什麼大的區別

"This method is a shortcut for .on( "load", handler )."

jquery API中提到$(window).load方法是$(window).on('load',handler)的shortcut,而且$(window).on('load',handler)相當於window.onload方法

$(window).load(function (){  
    // coding
});  
//等價於 JavaScript 中的以下代碼  
window.onload = function (){  
    // coding
} 

如果真要說區別的
$(window).load(handler)可以用多次使用,並且handler都會依次執行。但是window.onload就不行,就像上面介紹的一樣,window.onload = handler後面的hanlder會覆蓋之前的handler。

$(window).load(function() {  
    $("#btn-upload").click(function(){
        //coding upload
    });  
});  

注意:由於在$(document).ready()方法內註冊的事件,只要 DOM 就緒就會被執行,因此可能此時元素的關聯文件未下載完。例如與圖片有關的 html 下載完畢,並且已經解析爲 DOM 樹了,但很有可能圖片還沒有加載完畢,所以獲取圖片的高度和寬度這樣的屬性此時不一定有效。要解決這個問題,可以使用 jquery 中另一個關於頁面加載的方法 ---load() 方法。 Load() 方法會在元素的 onload 事件中綁定一個處理函數。如果處理函數綁定給 window 對象,則會在所有內容 ( 包括窗口、框架、對象和圖像等 ) 加載完畢後觸發,如果處理函數綁定在元素上,則會在元素的內容加載完畢後觸發。

用原生JS實現jQuery的ready方法

那麼,對於某些特殊需求,不希望使用jQuery,但又想實現jQuery的ready方法。該如何用原生JS實現jQuery的ready方法呢?下面是其中之一的做法::

function ready(fn){  
    if(document.addEventListener){      
        //標準瀏覽器  
        document.addEventListener('DOMContentLoaded',function(){  
            //註銷事件,避免反覆觸發  
            document.removeEventListener('DOMContentLoaded',arguments.callee,false); 
            //執行函數   
            fn();
        },false);  
    }else if(document.attachEvent){     
        //IE瀏覽器  
        document.attachEvent('onreadystatechange',function(){  
            if(document.readyState=='complete'){  
                document.detachEvent('onreadystatechange',arguments.callee);  
                //執行函數   
                fn();  
            }  
        });  
    }  
}

下面用一段代碼驗證ready函數的正確性:

window.onload = function(){
    console.log("window.onload event");
}
ready(function(){
    console.log('window ready event')
})

執行結果如下:
ready

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章