jQuery.imgLazyLoad圖片懶加載組件

一、前言

 

當一個頁面中請求的圖片過多,而且圖片太大,頁面訪問的速度是非常慢的,對用戶的體驗非常不友好;使用圖片懶加載,可以減輕服務器的壓力,增加頁面的訪問量,這裡主要是總結一下我自己寫的圖片懶加載組件jQuery.imgLazyLoad;使用該組件應在img標簽中設置一個imglazyload-src屬性,存放圖片地址。

 

二、應用實例demo

 

/**

 * component: imgLazyLoad 2013/12/12 華子yjh

 * invoking: jQuery.imgLazyLoad(options)

 *

    // 配置對象

    options = {

        container: 'body',              // 外圍容器,默認body

        tabItemSelector: '',            // Tab切換面板選擇器

        carouselItemSelector: '',       // 圖片輪播面板選擇器

        attrName: 'imglazyload-src'     // 圖片地址屬性

        diff: 300                       // 預加載像素

    }

 *

 */

 

圖片輪播懶加載:https://miiee.taobao.com

Tab切換圖片懶加載:https://miiee.taobao.com/main.htm

瀏覽器滾動圖片懶加載:https://miiee.taobao.com/themes/theme_151.htm

 

 

 

三、設計思路

 

1、處理瀏覽器下拉滾動

 

比較 $(window).scrollTop + $(window).height() 與 img.offset().top 的值,當圖片在瀏覽器窗口中,開始加載圖片

 

2、處理Tab切換 與 圖片輪播

 

在處理Tab切換 與 圖片輪播,組件提供瞭一個用於事件處理的函數 handleImgLoad,參數idx:

 

該參數對於圖片輪播,是作為下一輪輪播面板的索引,將下一輪輪播面板中的所有圖片預加載

對於Tab切換,則是作為tab項的索引,加載當前顯示tab項中的所有圖片

 

3、選擇器處理

 

3.1、滾動下拉選擇器的處理

 

在 配置對象中有一個attrName,是保持圖片地址的一個屬性 選擇器為:img[config.attrName];

 

其次圖片是顯示的,如果隱藏,則不加載圖片, 選擇器為:img[config.attrName]:visible;

 

再次如果圖片已加載,為其加上一個img-loaded的className,為瞭過濾已加載過的圖片,選擇器為:img[config.attrName]:visible:not(.img-loaded);

 

最後如果一個頁面使用多次組件,第一次使用時,當配置對象container為body子元素,第二次應該過濾前一次container匹配元素中的圖片,

依次類推,選擇器為:img[config.attrName]:visible:not(.img-loaded):not(jQuery.imgLazyLoad.selectorCache)

 

3.2、Tab切換、圖片輪播選擇器的處理

 

在 配置對象中有tabItemSelector 或 carouselItemSelector ,結合事件處理函數的參數idx,獲取當前Tab項或下一輪輪播面板中的圖片

選擇器為:tabItemSelector:eq(idx) img 或 carouselItemSelector:eq(idx) img

 

如果idx === undefined,選擇器為:tabItemSelector:visible img 或 carouselItemSelector:eq(0) img

我是根據我自己寫的jQuery組件自行判斷的 

 

四、組件源碼

 

 

$.extend({

    imgLazyLoad: function(options) {

        var config = {

                container: 'body',

                tabItemSelector: '',

                carouselItemSelector: '',

                attrName: 'imglazyload-src',

                diff: 0

            };

        $.extend( config, options || {} );

 

        var $container = $(config.container),

            offsetObj = $container.offset(),

            compareH = $(window).height() + $(window).scrollTop(),

 

            // 判斷容器是否為body子元素

            bl = $.contains( document.body, $container.get(0) ),

 

            // 過濾緩存容器中的圖片

            notImgSelector = jQuery.imgLazyLoad.selectorCache ? ':not(' + jQuery.imgLazyLoad.selectorCache + ')' : '',

            imgSelector = 'img[' + config.attrName + ']:visible' + notImgSelector,

            $filterImgs = $container.find(imgSelector),

 

            // 用於阻止事件處理

            isStopEventHandle = false,

            

            // 是否自動懶加載,為true時,綁定滾動事件

            isAutoLazyload = false;

 

        // 緩存容器為body子元素的圖片選擇器

        jQuery.imgLazyLoad.selectorCache = bl ? (jQuery.imgLazyLoad.selectorCache ? (jQuery.imgLazyLoad.selectorCache + ',' + config.container + ' img') : config.container + ' img') : jQuery.imgLazyLoad.selectorCache;

 

        function handleImgLoad(idx) {

            if (isStopEventHandle) {

                return;

            }

            /**

             處理Tab切換,圖片輪播,在處理$filterImgs時,沒有過濾img:not(.img-loaded),因為隻是在一個面板中,

             還有其他面板,如果再次觸發,可能$filterImgs.length為0,因此隻能在外圍容器中判斷過濾圖片length

            */            

            if ($container.find('img:not(.img-loaded)').length === 0) {

                isStopEventHandle = true;

            }

 

            var itemSelector = config.tabItemSelector || config.carouselItemSelector || '';

            if (itemSelector) {

                if (typeof idx !== undefined && idx >= 0) {

                    $filterImgs = $container.find(itemSelector).eq(idx).find('img');

                }

                else {

                    if (itemSelector === config.carouselItemSelector) {

                        $filterImgs = $container.find(itemSelector).eq(0).find('img');

                    }

                    else {

                        $filterImgs = $container.find(itemSelector + ':visible').find('img');

                    }

                }

            }

            else {

                $filterImgs = $filterImgs.not('.img-loaded'); // 自動懶加載,過濾已加載的圖片

                isAutoLazyload = true;

            }

 

            // 當外圍容器位置發生變化,需更新

            offsetObj = $container.offset();

 

            if ($filterImgs.length > 0) {

                $filterImgs.each(function(idx, elem) {

                    var $target = $(elem),

                        targetTop = $target.offset().top,

                        viewH = $(window).height() + $(window).scrollTop() + config.diff;

 

                    if (bl) {

                        $target.attr('src', $target.attr(config.attrName)).removeAttr(config.attrName).addClass('img-loaded');

                    }

                    // 內容在視窗中

                    if (viewH > targetTop) {

                        $target.attr('src', $target.attr(config.attrName)).removeAttr(config.attrName).addClass('img-loaded');

                    }

                });

            }

            else {

                // 處理滾動事件

                isStopEventHandle = true;

                $(window).unbind('resize scroll', handleImgLoad);

            }

        }

 

        handleImgLoad();

        if (isAutoLazyload) {

            $(window).bind('resize scroll', handleImgLoad);

        }

 

        // 提供事件處理函數

        return {

            handleImgLoad: handleImgLoad

        }

    }

});

 

// 保存非body子元素容器下的圖片選擇器

jQuery.imgLazyLoad.selectorCache = '';

 

五、實例應用代碼

 

// 輪播圖片 懶加載

(function(){

    var imgLazyLoadObj = $.imgLazyLoad({

        container: '#first-block-switch',

        carouselItemSelector: '.switch-content li'

    });

    $.switchable({

        wrapSelector: '#first-block-switch',

        contentSelector: '.switch-content',

        prevBtnSelector: '.prev',

        nextBtnSelector: '.next',

        triggerSelector: '.switch-nav',

        autoPlay: true,

        duration: 300,

        interval: 3000,

        handleImgLoad: imgLazyLoadObj.handleImgLoad

    });

}());

 

// 瀏覽器滾動 懶加載

$.imgLazyLoad({ diff: 300 });

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *