Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready


Posted in Javascript onNovember 24, 2015

还记不记得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();
     }
    })();

以上所述是三水点靠木小编给大家介绍的Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready的全部内容,希望大家喜欢。

Javascript 相关文章推荐
List the Codec Files on a Computer
Jun 18 Javascript
JS对URL字符串进行编码/解码分析
Oct 25 Javascript
javascript 进阶篇3 Ajax 、JSON、 Prototype介绍
Mar 14 Javascript
JavaScript调用堆栈及setTimeout使用方法深入剖析
Feb 16 Javascript
IE的fireEvent方法概述及应用
Feb 22 Javascript
浅析javascript中的Event事件
Dec 09 Javascript
js仿百度音乐全选操作
Jan 13 Javascript
angular 动态组件类型详解(四种组件类型)
Feb 22 Javascript
使用JavaScript进行表单校验功能
Aug 01 Javascript
layui中layer前端组件实现图片显示功能的方法分析
Oct 13 Javascript
jQuery实现动态控制页面元素的方法分析
Dec 20 jQuery
详解Node.js中的Async和Await函数
Feb 22 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
Nov 24 #Javascript
JS实现图片高亮展示效果实例
Nov 24 #Javascript
JS截取字符串实例详解
Nov 24 #Javascript
超漂亮的jQuery图片轮播特效
Nov 24 #Javascript
jquery实现移动端点击图片查看大图特效
Sep 11 #Javascript
jquery解析json格式数据的方法(对象、字符串)
Nov 24 #Javascript
Bootstrap每天必学之按钮(一)
Nov 24 #Javascript
You might like
法兰绒滤网冲泡
2021/03/03 冲泡冲煮
php防止恶意刷新与刷票的方法
2014/11/21 PHP
PHP下载远程图片并保存到本地方法总结
2016/01/22 PHP
thinkPHP5.1框架使用SemanticUI实现分页功能示例
2019/08/03 PHP
Aliyun Linux 编译安装 php7.3 tengine2.3.2 mysql8.0 redis5的过程详解
2020/10/20 PHP
jquery自动完成插件(autocomplete)应用之PHP版
2009/12/15 Javascript
用jquery生成二级菜单的实例代码
2013/06/24 Javascript
jquery中attr和prop的区别分析
2015/03/16 Javascript
jQuery获取及设置表单input各种类型值的方法小结
2016/05/24 Javascript
详解Javascript函数声明与递归调用
2016/10/22 Javascript
JavaScript对象引用与赋值实例详解
2017/03/15 Javascript
JavaScript中 DOM操作方法小结
2017/04/25 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
一份超级详细的Vue-cli3.0使用教程【推荐】
2018/11/15 Javascript
Nodejs对postgresql基本操作的封装方法
2019/02/20 NodeJs
layui动态绑定事件的方法
2019/09/20 Javascript
javascript递归函数定义和用法示例分析
2020/07/22 Javascript
浅谈鸿蒙 JavaScript GUI 技术栈
2020/09/17 Javascript
JS hasOwnProperty()方法检测一个属性是否是对象的自有属性的方法
2021/01/29 Javascript
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
在Python中处理XML的教程
2015/04/29 Python
基于Python实现ComicReaper漫画自动爬取脚本过程解析
2019/11/11 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
Python图像读写方法对比
2020/11/16 Python
健身场所或家用健身设备:Life Fitness
2017/11/01 全球购物
Armor Lux法国官方网站:水手服装、成衣和内衣
2020/05/26 全球购物
医学生自我鉴定范文
2013/11/08 职场文书
2014年五四青年节演讲稿范文
2014/04/22 职场文书
实验室标语
2014/06/21 职场文书
入党积极分子对十八届四中全会期盼的思想汇报
2014/10/17 职场文书
观后感格式
2015/06/19 职场文书
退休欢送会主持词
2015/07/01 职场文书
python opencv检测直线 cv2.HoughLinesP的实现
2021/06/18 Python
一篇文章带你复习java知识点
2021/06/28 Java/Android
Python字典的基础操作
2021/11/01 Python
Windows Server 版本 20H2 于 8 月 9 日停止支持,Win10 版本 21H1 将于 12 月结束支
2022/07/23 数码科技