Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
还记不记得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的全部内容,希望大家喜欢。
您可能感兴趣的文章:
- AJAX 验证框架13个
- jquery 框架使用教程 AJAX篇
- Jquery AJAX 框架的使用方法
- 基于JQuery框架的AJAX实例代码
- javascript之AJAX框架使用说明
- asp.net省市三级联动的DropDownList+Ajax的三种框架(aspnet/Jquery/ExtJs)示例
- 简单的前端js+ajax 购物车框架(入门篇)
- jQuery1.9.1针对checkbox的调整方法(prop)
- 零基础学习AJAX之AJAX框架
- jQuery 1.9.1源码分析系列(十)事件系统之绑定事件
- jQuery-1.9.1源码分析系列(十)事件系统之事件体系结构
- jQuery-1.9.1源码分析系列(十)事件系统之事件包装
- Jquery-1.9.1源码分析系列(十一)之DOM操作
- jQuery 1.9.1源码分析系列(十三)之位置大小操作
- jQuery 1.9.1源码分析系列(十四)之常用jQuery工具
- jQuery1.9.1源码分析系列(十六)ajax之ajax框架
- JQuery1——基础($对象,选择器,对象转换)
- JavaScript演示排序算法
- 2015-2016网页设计趋势分析 Web Design of Trends
- jQuery Ajax 跨域调用
- 移动端的长按事件
- jquery教程靠边站,一分钱不花让你免费学会jquery
- JQuery+Strusts1.x无刷新登录
- JavaScript 各种遍历方式详解
- jQuery菜单插件用法实例
- JQuery 初体验(建议学习jquery)
- Jquery实现的table最后一行添加样式的代码
- jQuery实现向下滑出的平滑下拉菜单效果
- jQuery 练习[一] 学习jquery的准备工作
- jquery获得页面元素的坐标值实现思路及代码
- 使用Browserify配合jQuery进行编程的超级指南
- jquery如何实现在加载完iframe的内容后再进行操作
- jquery $.ajax()取xml数据的小问题解决方法
- jQuery '行 4954 错误: 不支持该属性或方法' 的问题解决方法
- Jquery 表单取值赋值的一些基本操作
- jQuery实现复选框批量选择与反选的方法