标签:
源码3373-3461 :主要包含ready事件
// The deferred used on DOM ready var readyList; jQuery.fn.ready = function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; }; jQuery.extend({ // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Hold (or release) the ready event holdReady: function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we‘re already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); // Trigger any bound ready events if ( jQuery.fn.triggerHandler ) { jQuery( document ).triggerHandler( "ready" ); jQuery( document ).off( "ready" ); } } }); /** * The ready event handler and self cleanup method */ function completed() { document.removeEventListener( "DOMContentLoaded", completed, false ); window.removeEventListener( "load", completed, false ); jQuery.ready(); } 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 ); }; // Kick off the DOM ready check even if the user does not jQuery.ready.promise();
1.ready和load事件
ready事件会在DOM结构加载完成的时候执行,在load事件之前触发。
load事件在文档加载完毕,所有的元素,资源(图片,css,嵌入的iframe)加载完毕触发。大多数情况下,只需要DOM结构加载完毕就可以执行js代码。
IE9+和其他浏览器都支持了DOMContentLoaded事件,针对IE9以下版本的IE浏览器可以监听onreadystatechange。新版的jQuery是不兼容旧版的IE了,源码里面只监听DOMContentLoaded事件。
2.定义了readyList来存放异步队列Deferred,并且给jQuery对象添加了ready方法。如下图:
// The deferred used on DOM ready var readyList; jQuery.fn.ready = function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; };
3.继续是这句代码jQuery.ready.promise().done( fn );
3.1 首先ready是定义在jQuery下面的一个属性方法,用来触发readyList里面的函数执行,代码片段如下:
ready: function( wait ) { // 执行readyList里面的函数 readyList.resolveWith( document, [ jQuery ] ); }
3.2 给这个ready添加了一个属性方法promise,代码如下:
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // readyState有几个值:loading,interactive,complete if ( document.readyState === "complete" ) { // 如果已经加载,则异步去执行ready里面的函数 setTimeout( jQuery.ready ); } else { // 绑定事件 document.addEventListener( "DOMContentLoaded", completed, false ); // window.addEventListener( "load", completed, false ); } } return readyList.promise( obj ); };
3.3 document.readyState:loading(加载中),interactive(dom加载完毕),complete(dom和资源全部加载完毕)
3.4 绑定的completed函数为:
触发的时候也移除这个事件,因为只需要执行一次,并且调用ready方法,触发。
function completed() { document.removeEventListener( "DOMContentLoaded", completed, false ); window.removeEventListener( "load", completed, false ); jQuery.ready(); }
3.5 3461行代码jQuery.ready.promise();这里单独一行,是无论我们是否使用了ready,都会执行。
源码3468-3517
4. access:为集合中的元素设置或读取值,这个方法在内部被很多其它的函数调用,比如attr,text,css等。里面最终用到的是setAttribute等原生方法。
待续。。。
标签:
原文地址:http://www.cnblogs.com/mszhangxuefei/p/jQuery-005.html