还记不记得jQuery初始化函数jQuery.fn.init中有这样是一个分支

//document ready简便写法$(function(){…})
} else if( jQuery.isFunction( selector ) ) {returnrootjQuery.ready( selector );
}

  所以$(fn)===$(document).ready(fn)

  来看一下jQuery.fn.ready的源码

ready: function( fn ) {//Add the callback
jQuery.ready.promise().done( fn );return this;
}

  很明显在jQuery.ready.promise函数中设置了延时,当延时对象解决的时候执行fn函数。

  主要的处理流程:

  创建一个延时对象,并将文档准备好后的处理事件添加到该延时对象成功事件列表上

jQuery.ready.promise = function( obj ) {  if ( !readyList ) {readyList=jQuery.Deferred();    ...

  }returnreadyList.promise( obj );
}

  添加文档准备状态的监听函数(jQuery.ready.promise函数片段)

    //标准浏览器支持DOMContentLoaded事件} else if( document.addEventListener ) {//绑定DOMContentLoaded事件和响应函数,响应函数会解决延时document.addEventListener( "DOMContentLoaded", completed, false);//回退到window.onload事件绑定,所有的浏览器都支持window.addEventListener( "load", completed, false);//如果是IE事件模型} else{//确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全document.attachEvent( "onreadystatechange", completed );//回退到window.onload事件绑定,所有的浏览器都支持window.attachEvent( "onload", completed );//如果IE并且不是一个frame//不断地检查,看是否该文件已准备就绪var top = false;try{top= window.frameElement == null &&document.documentElement;}catch(e) {}if ( top &&top.doScroll ) {(functiondoScrollCheck() {if ( !jQuery.isReady ) {try{//Use the trick by Diego Perini//http://javascript.nwbox.com/IEContentLoaded/top.doScroll("left");}catch(e) {return setTimeout( doScrollCheck, 50);}//移除之前绑定的事件
detach();//执行延迟
jQuery.ready();}})();}}

  一旦监听到文档准备完成,则调用jQuery.ready执行延时对象的成功回调列表:即所有通过jQuery.ready(fn)【或jQuery(fn)】方式添加的函数fn。

//ready事件处理函数
completed = function( event ) {//readyState === "complete"在老版本IE上适用if ( document.addEventListener || event.type === "load" || document.readyState === "complete") {detach();jQuery.ready();}
},//清除ready事件绑定
detach = function() {if( document.addEventListener ) {document.removeEventListener("DOMContentLoaded", completed, false);window.removeEventListener("load", completed, false);}else{document.detachEvent("onreadystatechange", completed );window.detachEvent("onload", completed );}
};

//处理当DOM准备完成
jQuery.ready: function( wait ) {      ...        //设置DOM已经准备好的标志      jQuery.isReady = true;    ...   //执行绑定的延时事件   
readyList.resolveWith( document, [ jQuery ] );   //触发任何绑定的就绪事件   if( jQuery.fn.trigger ) {     jQuery( document ).trigger("ready").off("ready");   }
}

  整个过程就是如此。其中有一些小的知识点整理一下。

a. 文档加载状态document.readyState


  document.readyState用来判断文档加载状态,是一个只读属性,可能的值有:

  0-uninitialized:XML 对象被产生,但没有任何文件被加载。
  1-loading:加载程序进行中,但文件尚未开始解析。
  2-loaded:部分的文件已经加载且进行解析,但对象模型尚未生效。
  3-interactive:仅对已加载的部分文件有效,在此情况下,对象模型是有效但只读的。
  4-complete:文件已完全加载,代表加载成功。

  实例:

document.onreadystatechange = stateChange;//当页面加载状态改变的时候执行这个方法.
functionstateChange() {     if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入        alert("文档加载成功")     } }

  但是,老版本的Firefox并不支持document.readyState【最新的Firefox已经支持了】。所以想要兼容所有浏览器监听文档准备完成分两种情况来处理:

  - 标准浏览器使用addEventListener添加DOMContentLoaded和load监听,任何一个事件被触发即可

  - 老版本IE浏览器使用attachEvent添加onreadystatechange和onload来监听,任何一个被触发,并且onreadystatechange时document.readyState === "complete"即可。

  jQuery的处理也就是如此了

jQuery.ready.promise = function(){...  //标准浏览器支持DOMContentLoaded事件  else if( document.addEventListener ) {//绑定DOMContentLoaded事件和响应函数,响应函数会解决延时document.addEventListener( "DOMContentLoaded", completed, false);//回退到window.onload事件绑定,所有的浏览器都支持window.addEventListener( "load", completed, false);//如果是IE事件模型} else{//确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全document.attachEvent( "onreadystatechange", completed );//回退到window.onload事件绑定,所有的浏览器都支持window.attachEvent( "onload", completed );       ...}
}//ready事件处理函数
completed = function( event ) {//readyState === "complete"在老版本IE上适用if ( document.addEventListener || event.type === "load" || document.readyState === "complete") {detach();jQuery.ready();}
}

  

b.doScroll检测文档加载完成


  这是Diego Perini 发现的一种检测IE是否加载完成的方式。详细链接

  原理是当页面 DOM 未加载完成时调用 doScroll 方法时会产生异常。那么不断的取检测异常是否发生就可以知道文档有没有加载完成。当没有发生异常,表明文档加载完成了。

                (function doScrollCheck() {if ( !jQuery.isReady ) {try{//Use the trick by Diego Perini//http://javascript.nwbox.com/IEContentLoaded/top.doScroll("left");}catch(e) {return setTimeout( doScrollCheck, 50);}//移除之前绑定的事件
detach();//执行延迟
jQuery.ready();}})();

  如果觉得本文不错,请点击右下方【推荐】!

jQuery-1.9.1源码分析系列(六) 延时对象应用——jQuery.ready相关推荐

  1. 菜鸟读jQuery 2.0.3 源码分析系列(1)

    原文链接在这里,作为一个菜鸟,我就一边读一边写 jQuery 2.0.3 源码分析系列 前面看着差不多了,看到下面一条(我是真菜鸟),推荐木有入门或者刚刚JS入门摸不着边的看看,大大们手下留情,想一起 ...

  2. jQuery源码分析系列(一)初识jQuery

    一个工厂 (function(global, factory){"use strict"// operation_1 })(typedef window !== "und ...

  3. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  4. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  5. [转载]jQuery1.6.1源码分析系列

    转载:http://www.cnblogs.com/nuysoft/archive/2011/11/14/2248023.html [原创] jQuery1.6.1源码分析系列(停止更新) 作者:nu ...

  6. MyBatis 源码分析系列文章合集

    1.简介 我从七月份开始阅读MyBatis源码,并在随后的40天内陆续更新了7篇文章.起初,我只是打算通过博客的形式进行分享.但在写作的过程中,发现要分析的代码太多,以至于文章篇幅特别大.在这7篇文章 ...

  7. MyBatis 源码分析系列文章导读

    1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...

  8. Spring IOC 容器源码分析系列文章导读

    1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解.在写完 Spring IOC 容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了3天时间阅 ...

  9. Spring IOC 容器源码分析系列文章导读 1

    1. 简介 Spring 是一个轻量级的企业级应用开发框架,于 2004 年由 Rod Johnson 发布了 1.0 版本.经过十几年的迭代,现在的 Spring 框架已经非常成熟了.Spring ...

  10. dubbo源码分析系列(1)扩展机制的实现

    1 系列目录 dubbo源码分析系列(1)扩展机制的实现 dubbo源码分析系列(2)服务的发布 dubbo源码分析系列(3)服务的引用 dubbo源码分析系列(4)dubbo通信设计 2 SPI扩展 ...

最新文章

  1. nlp 优缺点 混淆度_NLP中文分词的评估指标
  2. 美团某程序员爆料:绩效背c的都要签pip!网友:pip就是变相劝退!
  3. php访问参数错误,phpcms参数错误怎么办
  4. c语言注释部分只能位于,福建省计算机等级考试二级C语言选择题复习资料
  5. 量子计算机模型取,Grover算法在单道量子计算模型下的实现
  6. 斐波那契数列快速算法详解
  7. 前端学习(2455):layout处理
  8. 日记 2014-5-18
  9. Pytorch入门-2
  10. python 统计英文词频
  11. Python with as 用法与原理
  12. 珠海格力工厂一线员工待遇如何?
  13. [转]Qt 之 QFileSystemWatcher
  14. jmeter web监听结果_监听器-聚合报告监听性能测试结果
  15. java字符串拆分 空字符_Java字符串拆分
  16. pdf照片显示正常打印时被翻转_明天开始打印准考证,你需要注意这些!
  17. 深入剖析ConcurrentHashMap(2)
  18. 微信直播教程:微信直播时如何做直播倒计时预告效果
  19. java面试宝典第五版,《程序员面试宝典(第5版)》和《Java程序员面试宝典(第4版)》的一些看法......
  20. Delphi7--多分支Case语句

热门文章

  1. DCMTK:修改DICOM文件的类
  2. VTK:图表之ConnectedComponents
  3. VTK:图表之ColorVerticesLookupTable
  4. OpenCV检测ArUco板
  5. Qt Creator可视化Chrome跟踪事件
  6. C++找到一个大于或等于n且为2的幂的数字p的算法实现(附完整源码)
  7. OpenGL创建一个GLFW窗口的实例
  8. OpenGL HDR渲染
  9. QT的QLocale类的使用
  10. QML基础类型之bool