(jQuery版本为2.0.3)
jq加载,有3种方法:
$(document).ready(function(){});
$(function(){});
$(document).on('ready',function(){});
1、$(document).ready(function(){});
$(document)为JQ对象,调用ready实例方法
见243行:
ready: function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; }
调用的是jQuery.ready.promise().done(fn);
见822行:
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 ); };readyList为预先申明的变量,未赋值。
函数执行后申明为jQuery.Deferred()。
最后把延迟对象返回出去,满足条件后触发fn函数。
if()else(),监听dom加载,最终调用的都是jQuery.ready方法(静态方法)
见385行:
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.trigger ) { jQuery( document ).trigger("ready").off("ready"); } }jQuery.isReady: falsejQuery.readyWait: 1这两个是预先定义的变量看函数执行:wait为nudefined,isReady为false。if ( wait === true ? --jQuery.readyWait : jQuery.isReady )不执行return
接着isReady位置为true,说明dom已经加载完毕,如果有几个地方同时监测dom加载,只执行一次。if ( wait !== true && --jQuery.readyWait > 0 ) 这个判断后面说。接着就是readyList.resolveWith( document, [ jQuery ] ),延迟对象执行fn。这里就加载完毕了。这个判断留在后面说。if ( jQuery.fn.trigger ) { jQuery( document ).trigger("ready").off("ready"); }
2、$(function(){});
看187行:
传入的是函数,在init方法里,经过一系列判断,最终执行的是rootjQuery.ready( selector );
rootjQuery为预先申明的$(document)。执行的还是$(document).ready()方法
3、$(document).on('ready',function(){});
看6548行:
jQuery(function(){}),这里主动触发,进入init,和上面2走的是同一条路线。
上面方法1的最后面,走到这里,判断trigger方法并且调用
if ( jQuery.fn.trigger ) { jQuery( document ).trigger("ready").off("ready"); }243行:
ready: function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; },
同上面方法1了。
最后说这个判断:
jQuery.isReady: false jQuery.readyWait: 1
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } if ( wait !== true && --jQuery.readyWait > 0 ) { return; }
看376行:
holdReady: function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }
这个方法是延迟dom加载
在dom加载之前,执行 $.holdReady(true),jQuery.readyWait变为2。
if ( wait !== true && --jQuery.readyWait > 0 ) 因为这里的--jQuery.readyWait后为1,返回不执行后面的延迟对象。
当调用$.holdReady(false)方法,里面调用jQuery.ready( true ),这里传入参数true
if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; }此时--jQuery.readyWait为1,继续执行
if ( wait !== true && --jQuery.readyWait > 0 ) { return; }这里--jQuery.readyWait后为0,不执行if里面,正常加载了,dom的延迟加载。