在網上經常會看到一些很長的網頁會消極式載入其中的圖片,我認為這是一種按需分配的做法,網頁只為那些想繼續瀏覽網頁的人載入後面的圖片,在不影響使用者體驗的前提下,最大程度地減少伺服器負擔和流量。目前,主要的購物網站都採用了這種載入方式。今天在一個網友的站裡發現一個圖片消極式載入的外掛程式,很好用,在這裡介紹一下。
先介紹一片消極式載入原理。我們需要先將圖片的真真實位址儲存在一個自訂的屬性中(屬性名稱任你發揮吧,這裡我用的是lazy-src),而圖片的src屬性中用一個佔位圖片來替代,這個佔位圖片當然是越小越好,它基本上只幹活、不露面。
<img src="images/placeholder.png" lazy-src="images/realimg.jpg" alt="" /><!-- 如果瀏覽器禁用了js,我們也不能不讓網頁顯示圖片撒,所以最好是加上下面一句備用代碼 --><noscript><img src="images/realimg.jpg" alt="" /></noscript>
首先。頁面開始載入時瀏覽器會擷取所有圖片在當前頁面中的位置並緩衝(擷取offset的值時,頁面的reflow會被引發),計算出可視地區,當圖片的位置出現在可視地區中,利用js動態地將圖片標籤中的src值替換成圖片真實的地址,這時,剛剛出現在可視地區的圖片便開始載入。
其次。當使用者向下滾動頁面時,通過js再次計算是否有圖片初次出現可視地區內,如果有,剛對這些圖片的src值進行替換,並開始載入真實圖片。為了避免重複操作引起的記憶體流失,需要在全部圖片載入完後,卸載掉相應的觸發事件。
最後。本文是將整個視窗看成是一個大容器,如果願意,也可以在頁面中設定一個小容器,在小容器中也同樣可以實現圖片的消極式載入。原理雖然簡單,但是應用是多樣的。
從下面的地址可以看到圖片消極式載入的示範,不過盡量使用相應的工具(firebug、Fiddler2)監測圖片消極式載入的效果。
http://www.threesnow.com/code/091/
圖片消極式載入外掛程式的代碼如下:
圖片消極式載入外掛程式代碼
(function( $ ){$.fn.imglazyload = function( options ){ var o = $.extend({ attr : 'lazy-src', container : window, event : 'scroll', fadeIn : false, threshold : 0, vertical : true }, options ), event = o.event, vertical = o.vertical, container = $( o.container ), threshold = o.threshold, // 將jQuery對象轉換成DOM數組便於操作 elems = $.makeArray( $(this) ), dataName = 'imglazyload_offset', OFFSET = vertical ? 'top' : 'left', SCROLL = vertical ? 'scrollTop' : 'scrollLeft', winSize = vertical ? container.height() : container.width(), scrollCoord = container[ SCROLL ](), docSize = winSize + scrollCoord; // 消極式載入的觸發器 var trigger = { init : function( coord ){ return coord >= scrollCoord && coord <= ( docSize + threshold ); }, scroll : function( coord ){ var scrollCoord = container[ SCROLL ](); return coord >= scrollCoord && coord <= ( winSize + scrollCoord + threshold ); }, resize : function( coord ){ var scrollCoord = container[ SCROLL ](), winSize = vertical ? container.height() : container.width(); return coord >= scrollCoord && coord <= ( winSize + scrollCoord + threshold ); } }; var loader = function( triggerElem, event ){ var i = 0, isCustom = false, isTrigger, coord, elem, $elem, lazySrc; // 自訂事件只要觸發即可,無需再判斷 if( event ){ if( event !== 'scroll' && event !== 'resize' ){ isCustom = true; } } else{ event = 'init'; } for( ; i < elems.length; i++ ){ isTrigger = false; elem = elems[i]; $elem = $( elem ); lazySrc = $elem.attr( o.attr ); if( !lazySrc || elem.src === lazySrc ){ continue; } // 先從緩衝擷取offset值,緩衝中沒有才擷取計算值, // 將計算值緩衝,避免重複擷取引起的reflow coord = $elem.data( dataName ); if( coord === undefined ){ coord = $elem.offset()[ OFFSET ]; $elem.data( dataName, coord ); } isTrigger = isCustom || trigger[ event ]( coord ); if( isTrigger ){ // 載入圖片 elem.src = lazySrc; if( o.fadeIn ){ $elem.hide().fadeIn(); } // 移除緩衝 $elem.removeData( dataName ); // 從DOM數組中移除該DOM elems.splice( i--, 1 ); } } // 所有的圖片載入完後卸載觸發事件 if( !elems.length ){ if( triggerElem ){ triggerElem.unbind( event, fire ); } else{ container.unbind( o.event, fire ); } $( window ).unbind( 'resize', fire ); elems = null; } }; var fire = function( e ){ loader( $(this), e.type ); }; // 綁定事件 container = event === 'scroll' ? container : $( this ); container.bind( event, fire ); $( window ).bind( 'resize', fire ); // 初始化 loader(); return this;};})( jQuery );
有關這個的外掛程式API說明如下:
attr string
存放圖片真真實位址的屬性名稱,與HTML對應,預設是lazy-src。
container dom & selector
預設的容器為window,可自訂容器。
event stirng
觸發圖片載入的事件類型,預設為window.onscroll事件
fadeIn boolean
是否使用jQuery的fadeIn效果來顯示,預設是false。
threshold number
頁面滾動到離圖片還有指定距離的時候就進行載入,預設是0。
vertical boolean
是否橫向滾動,預設為true(縱向)。
loadScript(增強版的功能) boolean
是否無阻塞載入javascript廣告圖片,預設為false。
註:轉載請註明出處,覺得有用請推薦。