jQuery.imgLazyLoad圖片懶加載組件

1、前言

當一個頁面中請求的圖片過多,並且圖片太大,頁面訪問的速度是很是慢的,對用戶的體驗很是不友好;使用圖片懶加載,能夠減輕服務器的壓力,增長頁面的訪問量,這裏主要是總結一下我本身寫的圖片懶加載組件jQuery.imgLazyLoad;使用該組件應在img標籤中設置一個imglazyload-src屬性,存放圖片地址。瀏覽器

2、應用實例demo

/**
 * component: imgLazyLoad 2013/12/12 華子yjh
 * invoking: jQuery.imgLazyLoad(options)
 *
    // 配置對象
    options = {
        container: 'body',              // 外圍容器,默認body
        tabItemSelector: '',            // Tab切換面板選擇器
        carouselItemSelector: '',       // 圖片輪播面板選擇器
        attrName: 'imglazyload-src'     // 圖片地址屬性
        diff: 300                       // 預加載像素
    }
 *
 */

圖片輪播懶加載:http://miiee.taobao.com
Tab切換圖片懶加載:http://miiee.taobao.com/main.htm
瀏覽器滾動圖片懶加載:http://miiee.taobao.com/themes/theme_151.htm緩存

 

3、設計思路

一、處理瀏覽器下拉滾動

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

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

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

該參數對於圖片輪播,是做爲下一輪輪播面板的索引,將下一輪輪播面板中的全部圖片預加載
對於Tab切換,則是做爲tab項的索引,加載當前顯示tab項中的全部圖片spa

三、選擇器處理

3.一、滾動下拉選擇器的處理

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

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

再次若是圖片已加載,爲其加上一個img-loaded的className,爲了過濾已加載過的圖片,選擇器爲:img[config.attrName]:visible:not(.img-loaded);component

最後若是一個頁面使用屢次組件,第一次使用時,當配置對象container爲body子元素,第二次應該過濾前一次container匹配元素中的圖片,
依次類推,選擇器爲:img[config.attrName]:visible:not(.img-loaded):not(jQuery.imgLazyLoad.selectorCache)htm

3.二、Tab切換、圖片輪播選擇器的處理

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

若是idx === undefined,選擇器爲:tabItemSelector:visible img 或 carouselItemSelector:eq(0) img
我是根據我本身寫的jQuery組件自行判斷的 

4、組件源碼

$.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 = '';

5、實例應用代碼

// 輪播圖片 懶加載
(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 });

 

轉載請註明出處:博客園華子yjh

相關文章
相關標籤/搜索