Home  >  Article  >  Web Front-end  >  Jquery1.9.1 source code analysis series (6) Delay object application jQuery.ready_jquery

Jquery1.9.1 source code analysis series (6) Delay object application jQuery.ready_jquery

WBOY
WBOYOriginal
2016-05-16 15:30:031102browse

Do you still remember that there is a branch in jQuery initialization function jQuery.fn.init

//document ready简便写法$(function(){…})
} else if ( jQuery.isFunction( selector ) ) {
 return rootjQuery.ready( selector );
}
  所以$(fn)===$(document).ready(fn)。
  来看一下jQuery.fn.ready的源码
ready: function( fn ) {
 // Add the callback
 jQuery.ready.promise().done( fn );
 return this;
}

It is obvious that the delay is set in the jQuery.ready.promise function, and the fn function is executed when the delay object is resolved.

Main processing flow:

Create a delay object and add the processing event after the document is ready to the success event list of the delay object.

jQuery.ready.promise = function( obj ) {
  if ( !readyList ) {
    readyList = jQuery.Deferred();
    ...
  }
 return readyList.promise( obj );
}

Add a listening function for document readiness status (jQuery.ready.promise function fragment)

 //标准浏览器支持DOMContentLoaded事件
 } else if ( document.addEventListener ) {
   //绑定DOMContentLoaded事件和响应函数,响应函数会解决延时
   document.addEventListener( "DOMContentLoaded", completed, false );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.addEventListener( "load", completed, false );
 //如果是IE事件模型
 } else {
   //确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全
   document.attachEvent( "onreadystatechange", completed );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.attachEvent( "onload", completed );
   //如果IE并且不是一个frame
   //不断地检查,看是否该文件已准备就绪
   var top = false;
   try {
    top = window.frameElement == null && document.documentElement;
   } catch(e) {}
   if ( top && top.doScroll ) {
    (function doScrollCheck() {
     if ( !jQuery.isReady ) {
      try {
       // Use the trick by Diego Perini
       // http://javascript.nwbox.com/IEContentLoaded/
       top.doScroll("left");
      } catch(e) {
       return setTimeout( doScrollCheck, 50 );
      }
      //移除之前绑定的事件
      detach();
      //执行延迟
      jQuery.ready();
     }
    })();
   }
  }

Once it is detected that the document is ready, call jQuery.ready to execute the success callback list of the delay object: that is, all function fn added through jQuery.ready(fn) [or jQuery(fn)].

//ready事件处理函数
completed = function( event ) {
 // readyState === "complete"在老版本IE上适用
 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
  detach();
  jQuery.ready();
 }
},
//清除ready事件绑定
detach = function() {
 if ( document.addEventListener ) {
  document.removeEventListener( "DOMContentLoaded", completed, false );
  window.removeEventListener( "load", completed, false );
 } else {
  document.detachEvent( "onreadystatechange", completed );
  window.detachEvent( "onload", completed );
 }
};

//处理当DOM准备完成
jQuery.ready: function( wait ) {      
 ...        
 //设置DOM已经准备好的标志      
 jQuery.isReady = true;   
 ...   
 //执行绑定的延时事件   
 readyList.resolveWith( document, [ jQuery ] );   
 //触发任何绑定的就绪事件   
 if ( jQuery.fn.trigger ) {     
  jQuery( document ).trigger("ready").off("ready");   
 } 
}

That’s the whole process. There are some small knowledge points to sort out.

a. Document loading status document.readyState

Document.readyState is used to determine the document loading status. It is a read-only attribute. Possible values ​​are:

 0-uninitialized: XML object is generated, but no file is loaded.
1-loading: The loading program is in progress, but the file has not yet started parsing.
2-loaded: Some files have been loaded and parsed, but the object model has not yet taken effect.
3-interactive: Only valid for part of the file that has been loaded. In this case, the object model is valid but read-only.
4-complete: The file has been completely loaded, which means the loading is successful.

Example:

document.onreadystatechange = stateChange;//当页面加载状态改变的时候执行这个方法.
function stateChange() {   
  if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入     
    alert("文档加载成功")   
  } 
}

However, the old version of Firefox does not support document.readyState [the latest Firefox already supports it]. Therefore, if you want to be compatible with all browsers, the monitoring document preparation needs to be processed in two situations:

- Standard browsers use addEventListener to add DOMContentLoaded and load listeners, and any event can be triggered

- The old version of IE browser uses attachEvent to add onreadystatechange and onload to monitor, any one is triggered, and document.readyState === "complete" when onreadystatechange.

That’s how jQuery handles it

jQuery.ready.promise = function(){
  ...
  //标准浏览器支持DOMContentLoaded事件
  else if ( document.addEventListener ) {
   //绑定DOMContentLoaded事件和响应函数,响应函数会解决延时
   document.addEventListener( "DOMContentLoaded", completed, false );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.addEventListener( "load", completed, false );
 //如果是IE事件模型
 } else {
   //确保在onload之前执行延时,可能时间比较迟,但是对于iframes来说比较安全
   document.attachEvent( "onreadystatechange", completed );
   //回退到window.onload事件绑定,所有的浏览器都支持
   window.attachEvent( "onload", completed );
       ...
  }
}
//ready事件处理函数
completed = function( event ) {
 // readyState === "complete"在老版本IE上适用
 if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
  detach();
  jQuery.ready();
 }
}

 b.doScroll detects that document loading is complete

This is a way discovered by Diego Perini to detect whether IE is loaded. Detailed link

The principle is that when the page DOM is not loaded, an exception will be generated when the doScroll method is called. Then you can know whether the document has been loaded by continuously checking whether an exception occurs. When no exception occurs, the document loading is complete.                                                                        

 (function doScrollCheck() {
     if ( !jQuery.isReady ) {
      try {
       // Use the trick by Diego Perini
       // http://javascript.nwbox.com/IEContentLoaded/
       top.doScroll("left");
      } catch(e) {
       return setTimeout( doScrollCheck, 50 );
      }
      //移除之前绑定的事件
      detach();
      //执行延迟
      jQuery.ready();
     }
    })();
The above is the entire content of the Jquery1.9.1 source code analysis series (6) jQuery.ready for delayed object application introduced to you by the editor of Script House. I hope you like it.

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn