jQuery ready方法實(shí)現(xiàn)原理詳解
今天閑來(lái)無(wú)事研究研究jQuery.ready()的內(nèi)部實(shí)現(xiàn),看JQ的源碼一頭霧水,由于自己很菜了,于是翻了翻牛人的播客,講述詳細(xì),收獲頗多。
先普及一下jquery.ready()和window.onload,window.onload事件是在頁(yè)面所有的資源都加載完畢后觸發(fā)的. 如果頁(yè)面上有大圖片等資源響應(yīng)緩慢, 會(huì)導(dǎo)致window.onload事件遲遲無(wú)法觸發(fā).所以出現(xiàn)了DOM Ready事件. 此事件在DOM文檔結(jié)構(gòu)準(zhǔn)備完畢后觸發(fā), 即在資源加載前觸發(fā).
jQuery中的ready方法實(shí)現(xiàn)了當(dāng)頁(yè)面加載完成后才執(zhí)行的效果,但他并不是window.onload或者doucment.onload的封裝,而是使用 標(biāo)準(zhǔn)W3C瀏覽器DOM隱藏api和IE瀏覽器缺陷來(lái)完成的,首先,我們來(lái)看jQuery的代碼
DOMContentLoaded = function() { //取消事件監(jiān)聽(tīng),執(zhí)行ready方法 if ( document.addEventListener ) { document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.ready(); } else if ( document.readyState === "complete" ) { document.detachEvent( "onreadystatechange", DOMContentLoaded ); jQuery.ready(); } };
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); //表示頁(yè)面已經(jīng)加載完成,直接調(diào)用 ready方法 if ( document.readyState === "complete" ) { //將 jQuery.ready壓入異步消息隊(duì)列,設(shè)置延遲時(shí)間1毫秒(注意,有些瀏覽器延遲不能小于4毫秒) setTimeout( jQuery.ready); } else if ( document.addEventListener ) // { //監(jiān)聽(tīng)DOM加載完成 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); //這里是為了確保所有ready執(zhí)行結(jié)束,如果DOMContentLoaded方法執(zhí)行了,將有一個(gè)狀態(tài)值 isReady被設(shè)置為true,因此, //ready方法一旦執(zhí)行,那么將只執(zhí)行一次,window.addEventListener中的ready 將被 return 中斷 window.addEventListener( "load", jQuery.ready, false ); } else { //低版本的IE瀏覽器 document.attachEvent( "onreadystatechange", DOMContentLoaded ); window.attachEvent( "onload", jQuery.ready ); var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) //剔除iframe的成分 { (function doScrollCheck() { if ( !jQuery.isReady ) { try { //根據(jù)bug來(lái)兼容低版本的IE http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { //由于低版本的IE 瀏覽器,onreadystatechange事件不可靠,因此需要根據(jù)各個(gè)bug來(lái)判斷頁(yè)面是否已加載完成 return setTimeout( doScrollCheck, 50 ); } jQuery.ready(); } })(); } } } return readyList.promise( obj ); };
ready: function( wait ) { if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { //判斷頁(yè)面是否已完成加載并且是否已經(jīng)執(zhí)行ready方法 return; } if ( !document.body ) { return setTimeout( jQuery.ready ); } jQuery.isReady = true; //指示ready方法已被執(zhí)行 if ( wait !== true && --jQuery.readyWait > 0 ) { return; } readyList.resolveWith( document, [ jQuery ] ); if ( jQuery.fn.trigger ) { jQuery( document ).trigger("ready").off("ready"); } },
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
web前端開(kāi)發(fā)JQuery常用實(shí)例代碼片段(50個(gè))
本文給大家展示50個(gè)jquery代碼片段,這些代碼能夠給你的javascript項(xiàng)目提供幫助,需要的朋友快來(lái)學(xué)習(xí)一下吧2015-08-08jQuery組件easyui基本布局實(shí)現(xiàn)代碼
這篇文章主要為大家詳細(xì)介紹了jQuery easyui基本布局實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08JS在IE下缺少標(biāo)識(shí)符的錯(cuò)誤
今天在使用一個(gè)jQuery的插件時(shí),發(fā)現(xiàn)在IE下總報(bào)錯(cuò),但在Firefox下就很正常,所報(bào)的錯(cuò)誤就是:缺少標(biāo)識(shí)符!2014-07-07EasyUI的TreeGrid的過(guò)濾功能的解決思路
這篇文章主要介紹了EasyUI的TreeGrid的過(guò)濾功能的解決思路,需要的朋友可以參考下2017-08-08jQuery讓控件左右移動(dòng)的三種實(shí)現(xiàn)方法
常用的方法就是把控件的CSS position屬性設(shè)置為relative或 absolute,大家也可以學(xué)習(xí)下本文提供的其他方法2013-09-09jQuery dialog 異步調(diào)用ashx,webservice數(shù)據(jù)的代碼
點(diǎn)擊按鈕,在彈出的jQuery.dialog中,顯示異步返回的數(shù)據(jù)。WebService可以寫復(fù)雜的函數(shù),ashx可以根據(jù)傳過(guò)來(lái)的參數(shù)調(diào)用不同的方法,達(dá)到同樣的效果。2010-08-08jquery.validate[.unobtrusive]和Bootstrap實(shí)現(xiàn)tooltip錯(cuò)誤提示問(wèn)題分析
這篇文章主要介紹了jquery.validate[.unobtrusive]和Bootstrap實(shí)現(xiàn)tooltip錯(cuò)誤提示問(wèn)題分析的相關(guān)資料,需要的朋友可以參考下2016-10-10