jQuery源码阅读(九)---ready函数理解
2017-07-17 21:24
477 查看
在jQuery对象创建的时候,即init函数中,有处理这么一种参数情况,当selector为函数时,
源码是这样的:
代码只有短短三行,下来一个一个看调用的函数。
上面的DOMContentLoaded事件处理函数如下:
可以看到,上面不论是哪种情况分支,都会最终调jQuery.ready()方法。也就是当文档加载完成时,总是会触发
以上是Ready部分的整体实现。下来再做一个简单的梳理:
相当于调用
而里面的回调函数
首先
同时将回调函数加入到ReadyList中,这个是为了管理多个回调函数。因为jQuery中可以多次使用
下来就是当页面加载成功时,调用jQuery.ready() 函数,去分别将ReadyList中的回调函数触发,这部分调的是
$(function(){ })表示跟
$(document).ready(function(){ })是一样的情况。
源码是这样的:
if(jQuery.isFunction(selector)) { //rootjQuery = $(document); return rootjQuery.ready(selector); //相当于调$(document).ready()方法。 }
$.fn.ready
上面的$(document).ready()相当于调jQuery的实例方法。我们来看看实例方法ready()的源码:
ready: function(fn){ jQuery.bindReady(); readyList.add(fn); return this; }
代码只有短短三行,下来一个一个看调用的函数。
bindReady函数相当于监听文档加载完成的函数,即添加事件处理程序。
bindReady: function(){ //文档的状态主要有五种情况: //UnInitialized:未开始加载 //Loading:加载程序进行中,但是文件还没有被解析; //Loaded:部分文件加载并解析,但是文档对象模型(DOM)还暂未生效 //Interactive:只对已加载的文件有效且DOM有效但是只读; //Complete: 文件已全部加载,表示加载成功。 if ( document.readyState === "complete" ) { return setTimeout( jQuery.ready, 1 ); //处理IE的问题,它会提前触发ready,所以延迟一下 } if ( document.addEventListener ) { //添加事件处理程序,监听DOMContentLoaded事件 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); //为什么还要监听load事件?因为load事件是可以缓存的,有缓存的话,会先触发load事件 window.addEventListener( "load", jQuery.ready, false ); } else if ( document.attachEvent ) { //IE事件处理函数 document.attachEvent( "onreadystatechange", DOMContentLoaded ); window.attachEvent( "onload", jQuery.ready ); // 后面这部分暂时没大看懂 var toplevel = false; try { toplevel = window.frameElement == null; } catch(e) {} if ( document.documentElement.doScroll && toplevel ) { doScrollCheck(); } } }
上面的DOMContentLoaded事件处理函数如下:
if ( document.addEventListener ) { DOMContentLoaded = function() { document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.ready(); }; } else if ( document.attachEvent ) { DOMContentLoaded = function() { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( document.readyState === "complete" ) { document.detachEvent( "onreadystatechange", DOMContentLoaded ); jQuery.ready(); } }; }
可以看到,上面不论是哪种情况分支,都会最终调jQuery.ready()方法。也就是当文档加载完成时,总是会触发
jQuery.ready函数
ready: function( wait ) { //表示延迟事件处理函数,其中jQuery.readywait是由jQuery.holdReady函数控制的。 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); } //表示DOM加载完成,并记录下状态 jQuery.isReady = true; if ( wait !== true && --jQuery.readyWait > 0 ) { return; } //执行回调函数,这部分函数是在底层模块的回调部分实现的,后面看到的时候再梳理。 readyList.fireWith( document, [ jQuery ] ); //触发ready函数 //考虑到这种用法:$(document).on('ready', function(){}) if ( jQuery.fn.trigger ) { jQuery( document ).trigger( "ready" ).off( "ready" ); } } }
以上是Ready部分的整体实现。下来再做一个简单的梳理:
$(function(){ console.log("Ready"); })
相当于调用
$(document).ready(function(){ console.log("Ready") });
而里面的回调函数
function(){ console.log("Ready") }是在页面加载完成之后触发,所以按照我们之前事件的思路,要先监听事件,添加事件处理函数,然后在事件被触发的时候才能去执行回调函数。而Ready的源码也是这种思路。
首先
bindReady函数监听文档加载完成事件,并定义事件处理函数
complete;
同时将回调函数加入到ReadyList中,这个是为了管理多个回调函数。因为jQuery中可以多次使用
$(function(){ })。
下来就是当页面加载成功时,调用jQuery.ready() 函数,去分别将ReadyList中的回调函数触发,这部分调的是
ReadyList.fireWith()方法,这个到后面看回调模块时会再整理。
相关文章推荐
- [SDS阅读理解/5]源码中的函数/2
- 01.阅读JQUERY源码——定义函数
- 简便使用jQuery-源码阅读全局架构设计的理解
- [SDS阅读理解/8]源码中的函数/5
- jquery源码阅读知识储备(9)javascrpt中的函数知识(待续)
- [SDS阅读理解/9]源码中的函数/6
- [SDS阅读理解/6]源码中的函数/3
- jQuery 的 ready 函数是如何工作的?(源码分析)
- jquery源码阅读知识储备(7)JS函数中的argument属性
- jquery源码阅读知识储(8)Javascript引用和作用域的理解
- [SDS阅读理解/7]源码中的函数/4
- hadoop源码阅读之mapreduce再理解
- 第十四周 程序阅读,理解虚函数与纯虚函数
- jQuery源码分析-03构造jQuery对象-工具函数
- 《理解 ES6》阅读整理:函数(Functions)(五)Name Property
- Deep Compression阅读理解及Caffe源码修改
- 【阅读】《head first jquery》第七章——定制函数提供定制效果(完善变脸小项目)
- FutureTask源码阅读与理解
- jquery 源码阅读笔记 大杂烩
- Jquery源码解析---利用队列来实现函数的顺序执行