圖片消極式載入【前端開發技能必備系列】

來源:互聯網
上載者:User

在網上經常會看到一些很長的網頁會消極式載入其中的圖片,我認為這是一種按需分配的做法,網頁只為那些想繼續瀏覽網頁的人載入後面的圖片,在不影響使用者體驗的前提下,最大程度地減少伺服器負擔和流量。目前,主要的購物網站都採用了這種載入方式。今天在一個網友的站裡發現一個圖片消極式載入的外掛程式,很好用,在這裡介紹一下。

先介紹一片消極式載入原理。我們需要先將圖片的真真實位址儲存在一個自訂的屬性中(屬性名稱任你發揮吧,這裡我用的是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。

 

註:轉載請註明出處,覺得有用請推薦。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.