jQuery源码阅读[2]document ready

先来看一下window.onload 和$(document).ready()的区别,window.onload是等整个页面全部加载完毕,而$(document).ready()只是等待DOM加载完毕,举个例子,比如img标签,window.onload是等图片加载完毕,而DOM加载只是加载这个DOM标签,不必等图片加载完毕。实际上jQuery调用的是DOMContentLoaded事件。

我们来看一下这样的用法:

$(function(){
    console.log("document ready");
});

让我们来回顾一下,$()即调用jQuery方法,在jQuery源码刚开始的地方我们就可以看到:

jQuery = function( selector, context ) {
	// The jQuery object is actually just the init constructor 'enhanced'
	return new jQuery.fn.init( selector, context, rootjQuery );
},

该方法调用了jQuery.fn.inti构造函数,即原型对象中的init方法,该方法会判断传入的参数,如果是一个函数,实际上调用的是$(document).ready(),所以$(function(){})和$(document).ready(function(){})是一样的

else if ( jQuery.isFunction( selector ) ) {
	return rootjQuery.ready( selector );    //在源码中有这样的赋值,rootjQuery = jQuery(document);
}

在jQuery的原型对象中可以找到ready函数,这实际上是每个jQuery对象的方法,从调用方式$(document).ready()中也可以看出来这是兑现方法。这个方法的源码是这样的:

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

	return this;
},


这里是调用jQuery这个对象的实例方法ready.promise,这个方法创建一个延迟对象,然后在适当的时候再调用穿进去的方法。来看一下jQuery.ready.promise()这个工具方法:

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

		readyList = jQuery.Deferred();

		// Catch cases where $(document).ready() is called after the browser event has already occurred.
		// we once tried to use readyState "interactive" here, but it caused issues like the one
		// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
		if ( document.readyState === "complete" ) {
			// Handle it asynchronously to allow scripts the opportunity to delay ready
			setTimeout( jQuery.ready );

		} else {

			// Use the handy event callback
			document.addEventListener( "DOMContentLoaded", completed, false );

			// A fallback to window.onload, that will always work
			window.addEventListener( "load", completed, false );
		}
	}
	return readyList.promise( obj );
};

在else中,为两个事件都添加了complete方法,DOMContentLoaded 和load事件,按理说DOMContentLoaded事件应该是在load之前就被触发,仍然监测这两个事件主要是为了确保在有些浏览器采用缓存策略的情况下仍可以正常触发complet方法,有些浏览器如火狐会缓存load事件,导致load事件在DOMContentLoaded事件之前触发,同时绑定这两个事件可以保证complete函数最快被触发。

我们来看一下complet函数,这个函数是在jQuery作用域里定义的一个全局的函数。在代码刚开始的地方:

completed = function() {
    document.removeEventListener( "DOMContentLoaded", completed, false );
    window.removeEventListener( "load", completed, false );
    jQuery.ready();
};

这个函数取消了complete函数的绑定以确保complet函数只会执行一次,最终实际上是调用了jQuery.ready这个工具方法,这与jQuery.ready.promise方法中readyState为complete情况下是一样的,也就是说

可以看到不管是if还是else,最终都会调用jQuery.ready这个方法,该方法是通过$.extend()扩展的一个工具方法:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值