Adakah anda masih ingat bahawa terdapat cawangan dalam fungsi permulaan jQuery 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; }
Adalah jelas bahawa kelewatan ditetapkan dalam fungsi jQuery.ready.promise, dan fungsi fn dilaksanakan apabila objek kelewatan diselesaikan.
Aliran pemprosesan utama:
Cipta objek kelewatan dan tambahkan acara pemprosesan selepas dokumen bersedia ke senarai acara kejayaan objek kelewatan.
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); ... } return readyList.promise( obj ); }
Tambah fungsi mendengar untuk status kesediaan dokumen (serpihan fungsi jQuery.ready.promise)
//标准浏览器支持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(); } })(); } }
Setelah dikesan bahawa dokumen itu sedia, panggil jQuery.ready untuk melaksanakan senarai panggil balik kejayaan objek kelewatan: iaitu, semua fungsi fn ditambah melalui jQuery.ready(fn) [atau 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"); } }
Itulah keseluruhan prosesnya. Terdapat beberapa titik pengetahuan kecil untuk diselesaikan.
a. Dokumen status memuatkan dokumen.readyState
Document.readyState digunakan untuk menentukan status pemuatan dokumen Ia adalah atribut baca sahaja
0-tidak dimulakan: Objek XML dijana, tetapi tiada fail dimuatkan.
1-pemuatan: Program pemuatan sedang berjalan, tetapi fail belum mula menghuraikan.
2-dimuatkan: Beberapa fail telah dimuatkan dan dihuraikan, tetapi model objek masih belum berkuat kuasa.
3-interaktif: Hanya sah untuk sebahagian daripada fail yang telah dimuatkan Dalam kes ini, model objek adalah sah tetapi baca sahaja.
4-lengkap: Fail telah dimuatkan sepenuhnya, yang bermaksud pemuatan berjaya.
document.onreadystatechange = stateChange;//当页面加载状态改变的时候执行这个方法. function stateChange() { if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入 alert("文档加载成功") } }
- Penyemak imbas standard menggunakan addEventListener untuk menambah DOMContentLoaded dan memuatkan pendengar, dan sebarang peristiwa boleh dicetuskan
- Versi lama pelayar IE menggunakan attachEvent untuk menambah onreadystatechange dan onload untuk memantau, mana-mana satu dicetuskan dan document.readyState === "lengkap" apabila onreadystatechange.
Begitulah cara jQuery mengendalikannya
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 mengesan bahawa pemuatan dokumen telah selesai
Prinsipnya ialah apabila DOM halaman tidak dimuatkan, pengecualian akan dijana apabila kaedah doScroll dipanggil. Kemudian anda boleh mengetahui sama ada dokumen telah dimuatkan dengan menyemak secara berterusan sama ada pengecualian berlaku. Apabila tiada pengecualian berlaku, pemuatan dokumen selesai.
(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(); } })();