jQuery ready方法原理

来源:互联网 发布:wap源码网站封装成app 编辑:程序博客网 时间:2024/05/29 12:32

$(document).ready(function) 在DOM结构就绪时就触发了,但是传统的window.onload则是在DOM加载完毕且所有资源都下载完毕后才触发。

ready是浏览器兼容的,那么就分为两种情况

  • 标准浏览器:标准浏览器非常简单,有 DOMContentLoaded 事件,当所有DOM解析完以后会触发这个事件
    这里写图片描述
  • 非标准浏览器
    非标准浏览器麻烦一些,jquery用两个方式来保证
    • 如果浏览器存在 document.onreadystatechange 事件,当该事件触发时,如果 document.readyState=complete 的时候,可视为 DOM 树已经载入
    • doScroll检测:IE浏览器文档中说明,当页面 DOM 未加载完成时,调用 doScroll 方法时,会产生异常。那么我们反过来用,如果不异常,那么就是页面DOM加载完毕了,可以不断地通过能否执行 doScroll 判断 DOM 是否加载完毕

因此总流程就是:

这里写图片描述

同时,为了保证最后一定会调用ready方法,在上面每一种方式的最后都还是会为load事件绑定ready方法。

if ( document.readyState === "complete" ) {      // Handle it asynchronously to allow scripts the opportunity to delay ready      //这里的setTimeout是为了异步      setTimeout( jQuery.ready, 1 );    // Standards-based browsers support DOMContentLoaded    //标准浏览器侦听事件接口:document.addEventListener    } else if ( document.addEventListener ) {      // Use the handy event callback      document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );      // A fallback to window.onload, that will always work      //文章一开始说了,这里为了保证一定会触发ready,所以还针对onload也绑定一次回调      window.addEventListener( "load", jQuery.ready, false );    // If IE event model is used    } else {      //IE侦听事件接口:document.attachEvent      //如果有onreadystatechange事件,侦听之      // Ensure firing before onload, maybe late but safe also for iframes      document.attachEvent( "onreadystatechange", DOMContentLoaded );      // A fallback to window.onload, that will always work      window.attachEvent( "onload", jQuery.ready );      // http://javascript.nwbox.com/IEContentLoaded/      // 见下边说明      // If IE and not a frame      // continually check to see if the document is ready      var top = false;      try {        top = window.frameElement == null && document.documentElement;      } catch(e) {}      //如果是IE并且不是iframe      if ( top && top.doScroll ) {        (function doScrollCheck() {          if ( !jQuery.isReady ) {            try {              // Use the trick by Diego Perini              // http://javascript.nwbox.com/IEContentLoaded/              //一直调用doScroll滚动,因为DOM渲染结束前,DOM节点是没有doScroll方法的,所以一直会异常              //直到DOM渲染结束了,这个时候doScroll方法不会抛出异常,然后就调用$.ready()              top.doScroll("left");            } catch(e) {              return setTimeout( doScrollCheck, 50 );            }            // and execute any waiting functions            jQuery.ready();          }        })();      }    }

参考文章:
jquery的ready方法实现原理
jQuery源码剖析(四)——$(document).ready