一、前言
當一個頁面中請求的圖片過多,而且圖片太大,頁面訪問的速度是非常慢的,對用戶的體驗非常不友好;使用圖片懶加載,可以減輕服務器的壓力,增加頁面的訪問量,這里主要是總結一下我自己寫的圖片懶加載組件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 // 預加載像素 } * */
圖片輪播懶加載:http://miiee.taobao.com
Tab切換圖片懶加載:http://miiee.taobao.com/main.htm
瀏覽器滾動圖片懶加載:http://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 });
轉載請注明出處:博客園華子yjh