Erinnern Sie sich noch daran, dass es in der jQuery-Initialisierungsfunktion jQuery.fn.init einen Zweig gibt?
//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; }
Es ist offensichtlich, dass die Verzögerung in der Funktion jQuery.ready.promise festgelegt ist und die Funktion fn ausgeführt wird, wenn das Verzögerungsobjekt aufgelöst wird.
Hauptverarbeitungsablauf:
Erstellen Sie ein Verzögerungsobjekt und fügen Sie das Verarbeitungsereignis hinzu, nachdem das Dokument bereit ist, zur Erfolgsereignisliste des Verzögerungsobjekts.
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); ... } return readyList.promise( obj ); }
Fügen Sie eine Überwachungsfunktion für den Dokumentbereitschaftsstatus hinzu (jQuery.ready.promise-Funktionsfragment)
//标准浏览器支持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(); } })(); } }
Sobald erkannt wird, dass das Dokument bereit ist, rufen Sie jQuery.ready auf, um die Erfolgsrückrufliste des Verzögerungsobjekts auszuführen: das heißt, alle über jQuery.ready(fn) [oder jQuery(fn)] hinzugefügten Funktionen 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"); } }
Das ist der ganze Prozess. Es gibt einige kleine Wissenspunkte, die geklärt werden müssen.
a. Dokumentladestatus document.readyState
Document.readyState wird verwendet, um den Ladestatus des Dokuments zu bestimmen. Es handelt sich um ein schreibgeschütztes Attribut
0-uninitialisiert: XML-Objekt wird generiert, aber keine Datei geladen.
1-loading: Das Ladeprogramm läuft, aber die Analyse der Datei hat noch nicht begonnen.
2-geladen: Einige Dateien wurden geladen und analysiert, aber das Objektmodell ist noch nicht wirksam.
3-interaktiv: Nur gültig für einen Teil der geladenen Datei. In diesem Fall ist das Objektmodell gültig, aber schreibgeschützt.
4-vollständig: Die Datei wurde vollständig geladen, was bedeutet, dass der Ladevorgang erfolgreich war.
document.onreadystatechange = stateChange;//当页面加载状态改变的时候执行这个方法. function stateChange() { if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入 alert("文档加载成功") } }
– Standardbrowser verwenden addEventListener, um DOMContentLoaded hinzuzufügen und Listener zu laden, und jedes Ereignis kann ausgelöst werden
– Die alte Version des IE-Browsers verwendet attachmentEvent, um onreadystatechange und onload zur Überwachung hinzuzufügen. Jeder wird ausgelöst und document.readyState === „vollständig“, wenn onreadystatechange.
So geht jQuery damit um
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 erkennt, dass das Laden des Dokuments abgeschlossen ist
Das Prinzip besteht darin, dass beim Aufruf der doScroll-Methode eine Ausnahme generiert wird, wenn das Seiten-DOM nicht geladen ist. Anschließend können Sie feststellen, ob das Dokument geladen wurde, indem Sie kontinuierlich prüfen, ob eine Ausnahme auftritt. Wenn keine Ausnahme auftritt, ist das Laden des Dokuments abgeschlossen.
(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(); } })();