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

//document ready简便写法$(function(){…})
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.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();     ...   }
return readyList.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 ) {
(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.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;//当页面加载状态改变的时候执行这个方法.
function stateChange() {   
  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源码分析系列(一)初识jQuery

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

  2. jQuery源码分析系列

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

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

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

  4. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  5. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  6. jquery2源码分析系列

    学习jquery的源码对于提高前端的能力很有帮助,下面的系列是我在网上看到的对jquery2的源码的分析.等有时间了好好研究下.我们知道jquery2开始就不支持IE6-8了,从jquery2的源码中 ...

  7. jQuery-1.9.1源码分析系列完毕目录整理

    jQuery 1.9.1源码分析已经完毕.目录如下 jQuery-1.9.1源码分析系列(一)整体架构 jQuery-1.9.1源码分析系列(一)整体架构续 jQuery-1.9.1源码分析系列(二) ...

  8. MyCat源码分析系列之——结果合并

    更多MyCat源码分析,请戳MyCat源码分析系列 结果合并 在SQL下发流程和前后端验证流程中介绍过,通过用户验证的后端连接绑定的NIOHandler是MySQLConnectionHandler实 ...

  9. MyCat源码分析系列之——SQL下发

    更多MyCat源码分析,请戳MyCat源码分析系列 SQL下发 SQL下发指的是MyCat将解析并改造完成的SQL语句依次发送至相应的MySQL节点(datanode)的过程,该执行过程由NonBlo ...

  10. MyCat源码分析系列之——BufferPool与缓存机制

    更多MyCat源码分析,请戳MyCat源码分析系列 BufferPool MyCat的缓冲区采用的是java.nio.ByteBuffer,由BufferPool类统一管理,相关的设置在SystemC ...

随机推荐

  1. USACO翻译:USACO 2013 NOV Silver三题

    USACO 2013 NOV SILVER 一.题目概览 中文题目名称 未有的奶牛 拥挤的奶牛 弹簧牛 英文题目名称 nocow crowded pogocow 可执行文件名 nocow crowde ...

  2. Linq中使用反射实现--LINQ通用数据表绑定DataGrid控件的方法(原创)

    项目需求,因为项目中存在很多表,这些表的内容需要呈现给客户浏览.转载请注明出处 相信很多写过程序的设计者很容易的用以下方式实现 在SqlConnect ,DataSet 的方式,我们很轻松的可以通过S ...

  3. 【转】WriteMessage的信息在AutoCAD中命令行中实时显示

    之前程序中有段发送信息到命令行上显示的代码,如下:     ed.WriteMessage("开始标注横断面高程,请稍候!");     但是发现命令行中并不马上显示,代码也明明运 ...

  4. easyUI datagrid 根据查询条件 选中对应数据的行

    开始 输入了 土豆,南瓜,再次是小青菜,每次输入点击搜索的时候(模糊查询),选中的当前数据对应的行 在做之前,在网上查询了许多资料,也在技术群里问过许多次,弄了好久终于好了. 第一次写博客真不知道写啥 ...

  5. 使用JDBC调用存储过程

    DELIMITER $$ DROP PROCEDURE IF EXISTS `jdbc`.`addUser` $$ ),in birthday date,in money float,out pid ...

  6. ENode框架Conference案例分析系列之 - ENode框架初始化

    前言 Conference案例是使用ENode框架来开发的.之前我没有介绍过ENode框架是如何启动的,以及启动时要注意的一些点,估计很多人对ENode框架的初始化这一块感觉很复杂,一头雾水.所以,本 ...

  7. 让linux好用起来--操作使用技巧

    让linux好用起来--操作使用技巧 1   概述 在一个初学者眼里,linux的 CLI 界面没有图形界面那样多彩和友好,会让人产生畏难心理,但是作为一个稍微进阶的linux玩家,自然会积累不少经验 ...

  8. [nRF51822] 13、浅谈nRF51822和NRF24LE1/NRF24LU1/NRF24L01经典2.4G模块无线通信配置与流程

    前言:  nRF51可以支持基于2.4G的互相通信.与NRF24LE1的通信.与NRF24LU1的通信.与NRF24L01的通信. 一.nRF51822基于2.4G和nRF51822通信 其中nRF5 ...

  9. 说说SQL Server 网络配置

    打开Sql Server Configuration Manager,里面显示了SQL Server的网络配置,这些到底表示什么含义呢? 图一:MSSQLSERVER的协议 这些配置选项,其实就是为了 ...

  10. 七天学会ASP.NET MVC (四)——用户授权认证问题

    小编应各位的要求,快马加鞭,马不停蹄的终于:七天学会 Asp.Net MVC 第四篇出炉,在第四天的学习中,我们主要了学习如何在MVC中如何实现认证授权等问题,本节主要讲了验证错误时的错误值,客户端验 ...