jQuery源码之ready()事件

来源:互联网 发布:kindle 软件下载 编辑:程序博客网 时间:2024/05/16 02:06

          jquery中,等待DOM加载完成再执行的方法ready事件,相信大家经常使用该事件,今天,我们来看下jquery源码中是如何实现该功能的。

一、实例

        首先看下,如何使用ready事件:

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

等DOM加载完成后,执行匿名函数,在控制台中打印1。

首先了解一下DOMContentLoaded与window.load()。

DOMContentLoaded是DOM构建完成后触发,window.onload()是等所有的内容加载完成,例如图片等等。DOMContentLoaded事件先触发,后触发window.onload()事件。


二、源码解析:


  1.函数及变量初始化


jQuery.extend({   isReady: false,   //DOM是否加载完毕,初始化为false   readyWait: 1,   //需要等待的事件,初始化为1 // Hold (or release) the ready eventholdReady: function( hold ) {  //是否要hold住ready事件。},// Handle when the DOM is readyready: function( wait ) {  //ready函数,执行ready事件是调用}});/** * The ready event handler and self cleanup method */function completed() {   //DOM完成后触发}jQuery.ready.promise = function( obj ) {   //ready事件调用的函数}

完成工具方法的扩展后,后面代码立即执行了:

2.执行 jQuery.ready.promise()

jQuery.ready.promise();

然我们看下该函数内部代码

jQuery.ready.promise = function( obj ) {if ( !readyList ) {     //第一次执行时readylist为undefined,进入ifreadyList = jQuery.Deferred();   //readyList为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:15if ( document.readyState === "complete" ) {  //如果DOM已经加载完了,我们不再触发complete事件,直接走ready// Handle it asynchronously to allow scripts the opportunity to delay readysetTimeout( jQuery.ready );} else {      // Use the handy event callbackdocument.addEventListener( "DOMContentLoaded", completed, false );  //给文档添加DOMContentLoaded事件// A fallback to window.onload, that will always workwindow.addEventListener( "load", completed, false );   //如果DOMContentLoade不执行,以此为备用,总是执行}}return readyList.promise( obj );  //返回状态不可改的Deferred对象};


3.执行jquery实例ready事件

当工具方法都初始化完之后,开始执行$(document).ready()中的ready().

jQuery.fn.ready = function( fn ) {// Add the callbackjQuery.ready.promise().done( fn );   //jQuery.ready.promise()函数,由于初始化工具方法时,已经执行过一遍,代码会直接返回Deferred对象。return this;                          //把入参添加到done中};

4.DOM树构造完成

触发complete事件

function completed() {document.removeEventListener( "DOMContentLoaded", completed, false ); //去除绑定的函数window.removeEventListener( "load", completed, false );jQuery.ready();   //执行工具方法的ready}

5.执行工具方法的ready方法

ready: function( wait ) {// Abort if there are pending holds or we're already readyif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {  //如果等待或者已经等待后了,跳过return;}// Remember that the DOM is readyjQuery.isReady = true;// If a normal DOM Ready event fired, decrement, and wait if need beif ( wait !== true && --jQuery.readyWait > 0 ) {return;}// If there are functions bound, to executereadyList.resolveWith( document, [ jQuery ] );   //触发resolveWith执行done中添加的函数// Trigger any bound ready eventsif ( jQuery.fn.triggerHandler ) {jQuery( document ).triggerHandler( "ready" );jQuery( document ).off( "ready" );}}});





0 0
原创粉丝点击