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

今天闲来无事研究研究jquery.ready()的内部实现,看JQ的源码一头雾水,因为本身很菜了,因而翻了翻牛人的播客,讲述详细,收获颇多。javascript

先普及一下jquery.ready()和window.onload,window.onload事件是在页面全部的资源都加载完毕后触发的. 若是页面上有大图片等资源响应缓慢, 会致使window.onload事件迟迟没法触发.因此出现了DOM Ready事件. 此事件在DOM文档结构准备完毕后触发, 即在资源加载前触发. html

个人ready方法写了2版,借鉴了很多前辈的代码,先上代码。java

代码1.0问世,代码以下:jquery

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问世,代码以下:spa

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也正在使用。code

这篇随笔也是边学边写,你们共同进步吧!htm

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

IE下IEcontentloaded的解决办法:http://javascript.nwbox.com/IEContentLoaded/

相关文章
相关标签/搜索