2012年4月2日

jQuery imagesLoaded 判斷圖片是否載入完成



jQuery imagesLoaded 簡介

簡介

jQuery imagesLoaded 是一個相當有用的jQuery外掛,它可以用來偵測網頁中的圖片使否已經成功載入,有人可能會問,偵測圖片已經成功載入能做甚麼!?因為圖片還沒成功載入前我們實無法取得圖片的寬度以及高度的,在許多Layout上的應用,取得圖片的寬與高是非常重要且必要的。

程式碼分析


$.fn.imagesLoaded = function(callback){ var elems = this.filter('img'), len = elems.length, blank = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; elems.bind('load.imgloaded',function(){ if (--len <= 0 && this.src !== blank){ elems.unbind('load.imgloaded'); callback.call(elems,this); } }).each(function(){ // cached images don't fire load sometimes, so we reset src. if (this.complete || this.complete === undefined){ var src = this.src; // data uri bypasses webkit log warning (thx doug jones) this.src = blank; this.src = src; } }); return this; };

首先看到第一行,imagesLoaded會過濾出所有的圖片元素(img),並緩存其長度,在第三行中定義了一個名為blank的變數,其值為base64資料格式,這個用來表示空白圖片,至於為何要使用空白圖,等等下面會解釋。
Base64是一種使用64基的位置計數法。它使用2的最大次方來代表僅可列印的ASCII 字元。這使它可用來作為電子郵件的傳輸編碼。在Base64中的變數使用字元A-Z、a-z和0-9 ,這樣共有62個字元,用來作為開始的64個數字,最後兩個用來作為數字的符號在不同的系統中而不同。 
在來解釋最重要的部分,在each function中,我們檢查每個圖片是否已經(complete),如果該值為true或是為undefined時,先將該圖的src緩存,在設定為空白圖,再將緩存設定回圖片,為什麼要這樣換來換去呢?


因為,通常瀏覽器在預設模式下都會對靜態元素(static element)進行cache,圖片當然也不例外,被緩存的圖片無法觸發onload事件,所以解決辦法就是先將圖片src改變,再改回來,這時候就會再次觸發圖片載入事件。

範例一 - 群組完成偵測


$('#my-container').imagesLoaded( function( $images, $proper, $broken ) { // callback provides three arguments: // $images: the jQuery object with all images // $proper: the jQuery object with properly loaded images // $broken: the jQuery object with broken images // `this` is a jQuery object of container console.log( $images.length + ' images total have been loaded in ' + this ); console.log( $proper.length + ' properly loaded images' ); console.log( $broken.length + ' broken images' ); });
<body> <div class="wrap"> <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy7FTlB5bSSvupxU0BJ8nGe9jOP5YMLfyD_m_i88W9QC3G4atjy1qMuo5J-Nyk5TgzLGJZocLt9xR139ObeKz98zsdjWzX8KJyPr2Z4PUIewqHi4frJ9xNd_9mhdaMbq9aOve6_OqNO9tX/s1600/finish_line_970825.jpg" /> <img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy7FTlB5bSSvupxU0BJ8nGe9jOP5YMLfyD_m_i88W9QC3G4atjy1qMuo5J-Nyk5TgzLGJZocLt9xR139ObeKz98zsdjWzX8KJyPr2Z4PUIewqHi4frJ9xNd_9mhdaMbq9aOve6_OqNO9tX/s1600/finish_line_970825.jpg" /> <img src="http://2.bp.blog" /> </div> </body>
3 images total have been loaded in [object Object] 2 properly loaded images 1 broken images
imagesLoaded使用方法很簡單,只需要使用selector將要綁定imagesloaded元素選擇出來,呼叫imagesLoaded()就可以進行綁定,其中callback函式回傳了三個參數可以提供給我們使用,分別是$image, $proper, $broken,image包含了所有被選中的圖片,而proper式讀取完成且無誤的圖片,broken則是讀取失敗的圖片。
上述範例中,圖片三故意將src設定為無效網址,所以輸出解果出現了一個broken。

範例二 - 單筆偵測


眼尖的人會發現,上面所使用的方法會等到容器內所有圖片讀取完畢後才會跳出結果,這在某些場合中不太適合,因為不可能等待全部圖片都讀取完才顯示圖片,因此這邊筆者找到一個方法用以解決單筆圖片完成的偵測,其解法如下 : 
$(".wrap img").each(function(){ $(this).imagesLoaded(function(){ console.log('loaded!!'); }); }); loaded!! loaded!!

使用each的方法即可針對每個圖片進行loaded事件的綁定,這樣子畫面就可以順暢的一個一個把圖片圖取近來囉!!


本文就簡介到這邊,如果有任何疑問歡迎留言告知。

沒有留言:

ShareThis