TimeStamp | You'll be challenged,inspired,motivated and humbled.nirvana

关于jquery中ready实现的原理[转]

转自http://hi.baidu.com/qq373793464/blog/item/8d55bee672d808e3b3fb95fd.html


ready: function( fn ) {//此方法其实是在jquery对象中init对象中的prototype中也在Jquery的fn对象的prototype中

          jQuery.bindReady();  //添加监听函数            

         if ( jQuery.isReady ) { //如果dom加载完成了             

           fn.call( document, jQuery );  //立刻执行函数            

        } else if ( readyList ) {            

           readyList.push( fn );  //否则把函数添加进readyList         

         }        

       return this; //返回调用的对象    

 },  

bindReady的实现

bindReady: function() {

      if ( readyBound ) {  //默认为false          return;      }    

          readyBound = true;   

       if ( document.readyState === "complete" ) {    //如果$().ready()的时候,document已经加载完成了.          

           return jQuery.ready();  //执行readyList里的方法      

        }      

         if ( document.addEventListener ) { //如果支持w3c标准事件模型, 如firefox opera, safari 

          document.addEventListener("DOMContentLoaded",DOMContentLoaded, false );   //当dom加载完成时, 触发DOMContentLoaded  

          window.addEventListener( "load", jQuery.ready, false );  //保险起见, 给window.onload上面也绑定jQuery.ready

        } else if ( document.attachEvent ) {   //如果是IE事件模型  

             document.attachEvent("onreadystatechange", DOMContentLoaded);  //实际上是document.readyState === "complete"时, 执行readyList里的函数      

             window.attachEvent( "onload", jQuery.ready ); //保险起见, 给window.onload上面也绑定jQuery.ready                          

              var toplevel = false;    

             try {

                       toplevel = window.frameElement == null;//判断是IE并且页面不在iframe当中             

              }  catch(e) {}          

              if ( document.documentElement.doScroll && toplevel ) {                

                      doScrollCheck(); //不停的执行document.documentElement.doScroll("left"); 直到不报异常 

              }         

      }     

 }  

jQuery.ready  

    ready: function() {         

            if ( !jQuery.isReady ) {

                if ( !document.body ) { //至少要保证document.body存在                  

                   return setTimeout( jQuery.ready, 13 );       //每隔13ms调用

                }                        

               jQuery.isReady = true;  //设置isReady                          

               if ( readyList ) {

                   var fn, i = 0;                 

                   while ( (fn = readyList[ i++ ]) ) {

                    fn.call( document, jQuery ); //依次执行readyList里的方法.                 

                   }                  

                   readyList = null;//清空readyList,尽早释放内存. 因为当isReady为true时,     

               }               

             if ( jQuery.fn.triggerHandler ) {//触发document上绑定的件                 

                 jQuery( document ).triggerHandler( "ready" );  

             }        

      }    

  }  


function doScrollCheck() {//ie下才有可能会调用

      if ( jQuery.isReady ) {          return;      }

        try { 

         document.documentElement.doScroll("left");

      } catch( error ) {

          setTimeout( doScrollCheck, 1 );

          return;

     }      //不停的执行document.documentElement.doScroll("left")      //直到没有异常抛出   

    jQuery.ready();  

}  


 

//这里是dom加载好执行的方法 

if ( document.addEventListener ) {//firefox 等浏览器的情况下

DOMContentLoaded = function() {

    document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );//移除事件

jQuery.ready();

};

} else if ( document.attachEvent ) {//ie下

DOMContentLoaded = function() {

     if ( document.readyState === "complete" ) {//状态为加载完成

     document.detachEvent( "onreadystatechange", DOMContentLoaded );//移除事件

     jQuery.ready();//调用

}

};

}

其实还想问的是~  如何能延迟加载JS ,不仅仅是JS判断所有DOM加载完成后再执行,而是在浏览器解析时,就把JS文件放在最后解析~~ ?

Feedback

你还可以输入600/600个字符 发表评论
称呼: (必填) 登录 | 开通博客
邮箱: (选填) 你的邮箱地址不会被公开
网站: (选填)
验证码: (必填)