jquery ready方法實現原理 內部原理


今天閑來無事研究研究jquery.ready()的內部實現,看JQ的源碼一頭霧水,由於自己很菜了,於是翻了翻牛人的播客,講述詳細,收獲頗多。

先普及一下jquery.ready()和window.onload,window.onload事件是在頁面所有的資源都加載完畢后觸發的. 如果頁面上有大圖片等資源響應緩慢, 會導致window.onload事件遲遲無法觸發.所以出現了DOM Ready事件. 此事件在DOM文檔結構准備完畢后觸發, 即在資源加載前觸發. 

我的ready方法寫了2版,借鑒了不少前輩的代碼,先上代碼。

代碼1.0問世,代碼如下:

var $ = ready = window.ready = function(fn){  
     if(document.addEventListener){//兼容非IE  
         document.addEventListener("DOMContentLoaded",function(){  
             //注銷事件,避免反復觸發  
             document.removeEventListener("DOMContentLoaded",arguments.callee,false);  
             fn();//調用參數函數  
         },false);  
     }else if(document.attachEvent){//兼容IE  
         document.onreadystatechange = function() {
             if (document.readyState == 'complete') {
                 document.onreadystatechange = null;
                 document.attachEvent("onreadystatechange",function(){
                     document.detachEvent("onreadystatechange",arguments.callee);
                     fn();//調用參數函數  
                 });  
             }
         };
     }  
 }
 
 ready(function(){
     alert(1);
 });

1.0是有問題的,對於不蛋疼的瀏覽器自然沒有事,可是遇到IE,大家要淡定。IE9完好沒有問題,可是IE6/7/8,就惡心了。

你們測試的時候最好頁面里裝一張巨大的圖片,每次都要強刷,你會發現IE6/7/8上我們寫的ready和onload沒有設那么兩樣!可能還會比onload還要慢!fuck!其實這個是onreadystatechange的問題,你要想讓他管用你頁面就別方圖了,大家是不是臉上一條黑線飄過,哎!我昨天買了塊表阿!

於是翻了篇大大的播客解決問題辦法來了。

代碼2.0問世,代碼如下:

var $ = ready = window.ready = function(fn){  
    if(document.addEventListener){//兼容非IE  
        document.addEventListener("DOMContentLoaded",function(){  
            //注銷事件,避免反復觸發  
            document.removeEventListener("DOMContentLoaded",arguments.callee,false);  
            fn();//調用參數函數  
        },false);  
    }else if(document.attachEvent){//兼容IE  
       IEContentLoaded (window, fn);
    }  

    function IEContentLoaded (w, fn) {
        var d = w.document, done = false,
        // only fire once
        init = function () {
            if (!done) {
                done = true;
                fn();
            }
        };
        // polling for no errors
        (function () {
            try {
                // throws errors until after ondocumentready
                d.documentElement.doScroll('left');
            } catch (e) {
                setTimeout(arguments.callee, 50);
                return;
            }
            // no errors, fire

            init();
        })();
        // trying to always fire before onload
        d.onreadystatechange = function() {
            if (d.readyState == 'complete') {
                d.onreadystatechange = null;
                init();
            }
        };
    }
}
ready(function(){alert(1)})

你們測試的時候最好頁面里裝一張巨大的圖片,然后再試試問題解決了。IE那塊IEcontentloaded代碼原理也不難看懂,一國外牛人所寫,好似jquery也正在使用。

這篇隨筆也是邊學邊寫,大家共同進步吧!

牛人播客:http://www.cnblogs.com/haogj/archive/2013/01/15/2861950.html

IE下IEcontentloaded的解決辦法:http://javascript.nwbox.com/IEContentLoaded/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM