jquery ready方法实现原理 内部原理

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/

原文地址:https://www.cnblogs.com/Leo_wl/p/3170502.html