亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

JavaScript的jQuery庫中ready方法的學習教程

2019-11-20 11:49:24
字體:
來源:轉載
供稿:網友

學習 jQuery 有許多途徑,我們今天從 jQuery 的 ready 函數開始。本例中的代碼都來自于 jQuery 腳本庫。

如果你使用過 jQuery , 就必然使用過 ready 函數,它用來注冊當頁面準備好之后可以執行的函數。

問題來啦,我們的頁面什么時候準備好了呢?

onload 事件
最基本的處理方式就是頁面的 onload 事件,我們在處理這個事件的時候,可以有多種方式,即可以通過 HTML 方式,直接寫在 body 元素的開始標記中,也可以使用事件注冊的方式來使用,這又可以分為 DOM0 方式和 DOM2 方式。再考慮到瀏覽器的兼容性,使用 DOM2 方式寫出來,如下所示。

if (document.addEventListener) {  // A fallback to window.onload, that will always work  window.addEventListener("load", jQuery.ready, false);  // If IE event model is used} else {  // A fallback to window.onload, that will always work  window.attachEvent("onload", jQuery.ready);}


 

DOMContentLoaded 事件
不過 onload 事件要等到所有頁面元素加載完成才會觸發, 包括頁面上的圖片等等。如果網頁上有大量的圖片,效果可想而知,用戶可能在沒有看到圖片的時候,就已經開始操作頁面了,而這時我們的頁面還沒有初始化,事件還沒有注冊上,這豈不是太晚了!

除了大家熟知的 onload 事件之外, 與 DOM 中的 onload 事件相近的,我們還有 DOMContentLoaded 事件可以考慮, 基于標準的瀏覽器支持這個事件,  當所有 DOM 解析完以后會觸發這個事件。

這樣,對于基于標準的瀏覽器來說,我們還可以注冊這個事件的處理。這樣,我們可能更早地捕獲到加載完成的事件。

if (document.addEventListener) {  // Use the handy event callback  document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);  // A fallback to window.onload, that will always work  window.addEventListener("load", jQuery.ready, false);}

onreadystatechange 事件
不標準的瀏覽器怎么辦呢?

如果瀏覽器存在 document.onreadystatechange 事件,當該事件觸發時,如果 document.readyState=complete 的時候,可視為 DOM 樹已經載入。

不過,這個事件不太可靠,比如當頁面中存在圖片的時候,可能反而在 onload 事件之后才能觸發,換言之,它只能正確地執行于頁面不包含二進制資源或非常少或者被緩存時作為一個備選吧。

if (document.addEventListener) {  // Use the handy event callback  document.addEventListener("DOMContentLoaded", DOMContentLoaded, false);  // A fallback to window.onload, that will always work  window.addEventListener("load", jQuery.ready, false);  // If IE event model is used} else {  // Ensure firing before onload, maybe late but safe also for iframes  document.attachEvent("onreadystatechange", DOMContentLoaded);  // A fallback to window.onload, that will always work  window.attachEvent("onload", jQuery.ready);}

DOMContentLoaded 函數在做什么呢?最終還是要調用 jQuery.ready 函數。

DOMContentLoaded = function() {  if ( document.addEventListener ) {    document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );    jQuery.ready();  } else if ( document.readyState === "complete" ) {    // we're here because readyState === "complete" in oldIE    // which is good enough for us to call the dom ready!    document.detachEvent( "onreadystatechange", DOMContentLoaded );    jQuery.ready();  }} 
doScroll 檢測法
MSDN 關于 JScript 的一個方法有段不起眼的話,當頁面 DOM 未加載完成時,調用 doScroll 方法時,會產生異常。那么我們反過來用,如果不異常,那么就是頁面DOM加載完畢了!

Diego Perini 在 2007 年的時候,報告了一種檢測 IE 是否加載完成的方式,使用 doScroll 方法調用。詳細的說明見這里。
原理是對于 IE 在非 iframe 內時,只有不斷地通過能否執行 doScroll 判斷 DOM 是否加載完畢。在本例中每間隔 50 毫秒嘗試去執行 doScroll,注意,由于頁面沒有加載完成的時候,調用 doScroll 會導致異常,所以使用了 try -catch 來捕獲異常。

(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);    }    // and execute any waiting functions    jQuery.ready();  }})();

document.readyState 狀態
如果我們注冊 ready 函數的時間點太晚了,頁面已經加載完成之后,我們才注冊自己的 ready 函數,那就用不著上面的層層檢查了,直接看看當前頁面的 readyState 就可以了,如果已經是 complete ,那就可以直接執行我們準備注冊的 ready 函數了。不過 ChrisS 報告了一個很特別的錯誤情況,我們需要延遲一下執行。

setTimeout 經常被用來做網頁上的定時器,允許為它指定一個毫秒數作為間隔執行的時間。當被啟動的程序需要在非常短的時間內運行,我們就會給她指定一個很小的時間數,或者需要馬上執行的話,我們甚至把這個毫秒數設置為0,但事實上,setTimeout有一個最小執行時間,當指定的時間小于該時間時,瀏覽器會用最小允許的時間作為setTimeout的時間間隔,也就是說即使我們把setTimeout的毫秒數設置為0,被調用的程序也沒有馬上啟動。

這個最小的時間間隔是多少呢?這和瀏覽器及操作系統有關。在John Resig的新書《Javascript忍者的秘密》一書中提到

    Browsers all have a 10ms minimum delay on OSX and a(approximately) 15ms delay on Windows.(在蘋果機上的最小時間間隔是10毫秒,在Windows系統上的最小時間間隔大約是15毫秒)

,另外,MDC中關于setTimeout的介紹中也提到,Firefox中定義的最小時間間隔(DOM_MIN_TIMEOUT_VALUE)是10毫秒,HTML5定義的最小時間間隔是4毫秒。既然規范都是這樣寫的,那看來使用setTimeout是沒辦法再把這個最小時間間隔縮短了。

這樣,通過設置為 1, 我們可以讓程序在瀏覽器支持的最小時間間隔之后執行了。

// 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") {  // 延遲 1 毫秒之后,執行 ready 函數  setTimeout(jQuery.ready, 1);} 


 

完整的代碼
在 jQuery 中完整的代碼如下所示。位于 jQuery 1.8.3 源代碼的 #842 行。

jQuery.ready.promise = function( obj ) {  if ( !readyList ) {    readyList = jQuery.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:15    if ( document.readyState === "complete" ) {      // Handle it asynchronously to allow scripts the opportunity to delay ready      setTimeout( jQuery.ready, 1 );    // Standards-based browsers support DOMContentLoaded    } else if ( document.addEventListener ) {      // Use the handy event callback      document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );      // A fallback to window.onload, that will always work      window.addEventListener( "load", jQuery.ready, false );    // If IE event model is used    } else {      // Ensure firing before onload, maybe late but safe also for iframes      document.attachEvent( "onreadystatechange", DOMContentLoaded );      // A fallback to window.onload, that will always work      window.attachEvent( "onload", jQuery.ready );      // If IE and not a frame      // continually check to see if the document is ready      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 );            }            // and execute any waiting functions            jQuery.ready();          }        })();      }    }  }  return readyList.promise( obj );};

那么,又是誰來調用呢?當然是需要的時候,在我們調用 ready 函數的時候,才需要注冊這些判斷頁面是否完全加載的處理,這段代碼在 1.8.3 中位于代碼的 #244 行,如下所示:

ready: function( fn ) {  // Add the callback  jQuery.ready.promise().done( fn );  return this;}

在頁面上引用 jQuery 腳本庫之后,執行了 jQuery 的初始化函數,初始化函數中創建了 ready 函數。我們在通過 ready 函數注冊事件處理之前,jQuery 完成了頁面檢測代碼的注冊。這樣。當頁面完全加載之后,我們注冊的函數就被調用了。


jQuery Ready 方法的簡短寫法

寫 jQuery 代碼的時候,一般要寫一個 Ready 方法,以確保 DOM 已加載完畢,然后再執行相應的 jQuery 代碼。Ready 方法一般寫法如下:

$(document).ready(function() {  // 從這里開始});

但是在看其他人寫的 jQuery 代碼的時候,經常又會看到如下寫法:

$(function() {  // 從這里開始});

第二種寫法雖然簡短了許多,但是在功能上和第一種寫法是等價的,如果你不相信,可以看一下 jQuery 的源代碼中有如下代碼片段:

// HANDLE: $(function)// Shortcut for document ready if ( jQuery.isFunction( selector ) ) {  return rootjQuery.ready( selector );}

如果傳入選擇器中的參數是一個函數,那么會自動返回一個 rootjQuery.ready( selector ),而 rootjQuery 又是 jQuery(document) 的一個引用,所以這里就相當于調用 jQuery(document).ready() 方法,而之前的那個匿名方法亦被傳入其中以備執行。

這種簡短寫法雖說減少了了一點代碼量,但是可讀性稍差,所以我個人還是傾向于前面的第一種寫法,特別是在團隊開發中,僅僅是為了語意明確。


 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
黑人极品videos精品欧美裸| 欧美在线精品免播放器视频| 8050国产精品久久久久久| 国产精品久久综合av爱欲tv| 亚洲一区国产精品| 久久久国产视频91| 97在线观看免费| 日韩中文字幕亚洲| 成人在线视频网站| 国产精品日韩欧美综合| 欧美另类高清videos| 日韩女优在线播放| 国模极品一区二区三区| 91精品国产高清久久久久久| 最好看的2019的中文字幕视频| 欧美成人免费小视频| 国产精品日韩久久久久| 91欧美日韩一区| 国产精品成av人在线视午夜片| 日韩中文字幕在线精品| 亚洲精品国产电影| 奇米一区二区三区四区久久| 欧美高清性猛交| 亚洲国产毛片完整版| 欧美不卡视频一区发布| 久久99精品国产99久久6尤物| 精品美女久久久久久免费| 成人精品一区二区三区电影免费| 国产一区二区视频在线观看| 亚洲大尺度美女在线| 欧美成人国产va精品日本一级| 国内精品久久久| 国产精品精品一区二区三区午夜版| 日韩女优人人人人射在线视频| 亚洲女人被黑人巨大进入al| 欧美精品在线免费播放| 国产精品69久久久久| 在线观看中文字幕亚洲| 国产亚洲免费的视频看| 国产成人短视频| 亚洲精品国产精品国产自| 一本色道久久88亚洲综合88| 欧美乱大交xxxxx| 亚洲最大中文字幕| 福利一区福利二区微拍刺激| 日韩欧美在线国产| 亚洲成人a级网| 2019最新中文字幕| 国产91精品最新在线播放| 欧美日韩免费区域视频在线观看| 日韩视频永久免费观看| 亚洲男人天堂2024| 欧美另类暴力丝袜| 亚洲天堂av在线免费观看| 在线观看91久久久久久| 亚洲国产精品久久久久| 尤物九九久久国产精品的分类| 国产精品9999| 亚洲国产小视频在线观看| 亚洲第一精品福利| 成人午夜小视频| 午夜精品一区二区三区在线视频| 欧美精品在线免费观看| 欧美亚洲伦理www| 主播福利视频一区| 97国产成人精品视频| 久久艳片www.17c.com| 成人国产精品免费视频| 欧美成人三级视频网站| 亚洲激情视频在线观看| 国产成人高清激情视频在线观看| 欧美亚洲日本网站| 久久久日本电影| 亚洲欧美国产日韩天堂区| 亚洲人成网站777色婷婷| 欧美成人性生活| 亚洲www在线| 亚洲午夜性刺激影院| 国产午夜精品一区理论片飘花| 91香蕉亚洲精品| 日韩高清av一区二区三区| 国产专区欧美专区| 中文日韩在线观看| 91精品久久久久久久久久久久久| 18一19gay欧美视频网站| 尤物九九久久国产精品的特点| 欧美性少妇18aaaa视频| 国产精品亚洲激情| xx视频.9999.com| 久久亚洲综合国产精品99麻豆精品福利| 一本色道久久88亚洲综合88| 国产精品99久久久久久久久| 91香蕉亚洲精品| 97国产精品免费视频| 国产欧美韩国高清| 国产成人涩涩涩视频在线观看| 成人午夜在线视频一区| 亚洲精品一区二三区不卡| 日韩av在线免费播放| 国产精品wwww| 亚洲精品视频久久| 中文字幕免费精品一区| 国产一区av在线| 亚洲精品资源在线| 成人黄色免费片| 欧美精品成人91久久久久久久| 欧美日韩国产一中文字不卡| 欧美日韩日本国产| 精品中文字幕在线| 亚洲电影免费观看高清完整版在线观看| 欧美自拍视频在线观看| 国产成人91久久精品| 国产精品欧美在线| 久久69精品久久久久久久电影好| 亚洲欧美成人在线| 亚洲一区二区免费在线| 欧美电影免费观看网站| 精品国产一区二区三区久久久狼| 亚洲精品国偷自产在线99热| 日韩精品免费电影| 午夜精品国产精品大乳美女| 国产精品普通话| 日韩在线精品视频| 日韩大片免费观看视频播放| 欧美在线xxx| 在线日韩欧美视频| 亚洲成人av片在线观看| 久久91精品国产| 欧美最顶级丰满的aⅴ艳星| 97精品视频在线| 日韩欧美国产视频| 97在线免费观看| 亚洲午夜未满十八勿入免费观看全集| 一个人看的www欧美| 久久影院资源站| 成人av资源在线播放| 久久精品国产2020观看福利| 尤物精品国产第一福利三区| 在线观看国产成人av片| 亚洲精选在线观看| 日韩高清中文字幕| 日韩国产欧美精品一区二区三区| 国产精品久久久久久久久久小说| 国产成人精品电影| 欧美老少做受xxxx高潮| 国产精品看片资源| 欧美日韩中文在线观看| 中文字幕在线精品| 久久国产精品亚洲| 亚洲精品白浆高清久久久久久| 国产视频精品久久久| 精品亚洲国产视频| 亚洲国产小视频| 亚洲直播在线一区| 国产精品久久久久久av福利| 久久影院免费观看| 国产欧美日韩最新| 91久久久久久国产精品| 欧美大片在线影院| 97国产精品免费视频| 日韩一区二区三区在线播放| 久久久久久久久中文字幕| 国产精品久久99久久| 97视频在线观看视频免费视频|