在網(wǎng)頁(yè)中,常常需要用到圖片,而圖片需要消耗較大的流量。正常情況下,瀏覽器會(huì)解析整個(gè)HTML代碼,然后從上到下依次加載<img src="xxx"> 的圖片標(biāo)簽。如果頁(yè)面很長(zhǎng),隱藏在頁(yè)面下方的圖片其實(shí)已經(jīng)被瀏覽器加載了。如果用戶不向下滾動(dòng)頁(yè)面,就沒有看到這些圖片,相當(dāng)于白白浪費(fèi)了圖片的流量。
所以,淘寶、京東這些流量非常巨大的電商,商品介紹頁(yè)又必須有大量的圖片,因此,這些頁(yè)面的圖片都是“按需加載”,即用戶滾動(dòng)頁(yè)面時(shí)顯示出來(lái)的時(shí)候才加載圖片。當(dāng)網(wǎng)速非常快的時(shí)候,用戶并不能感知懶加載的動(dòng)作,既省流量又不影響用戶瀏覽。
本文給出一種利用jQuery實(shí)現(xiàn)圖片懶加載的原理。它的基本思想是:在輸出HTML的時(shí)候,不要直接輸出<img src="xxx" ,而是輸出如下的img 標(biāo)簽:
<img src="/static/loading.gif" data-src="http://真正的圖片地址/xxx.jpg">
因此,頁(yè)面顯示的圖片是一個(gè)gif加載動(dòng)畫。當(dāng)頁(yè)面滾動(dòng)時(shí),如果圖片出現(xiàn)在屏幕中,就利用jQuery把<img> 的src 屬性替換為data-src 的內(nèi)容,瀏覽器就會(huì)實(shí)時(shí)加載。
JavaScript代碼如下:
// 注意: 需要引入jQuery和underscore
$(function() {
// 獲取window的引用:
var $window = $(window);
// 獲取包含data-src屬性的img,并以jQuery對(duì)象存入數(shù)組:
var lazyImgs = _.map($('img[data-src]').get(), function (i) {
return $(i);
});
// 定義事件函數(shù):
var onScroll = function() {
// 獲取頁(yè)面滾動(dòng)的高度:
var wtop = $window.scrollTop();
// 判斷是否還有未加載的img:
if (lazyImgs.length > 0) {
// 獲取可視區(qū)域高度:
var wheight = $window.height();
// 存放待刪除的索引:
var loadedIndex = [];
// 循環(huán)處理數(shù)組的每個(gè)img元素:
_.each(lazyImgs, function ($i, index) {
// 判斷是否在可視范圍內(nèi):
if ($i.offset().top - wtop < wheight) {
// 設(shè)置src屬性:
$i.attr('src', $i.attr('data-src'));
// 添加到待刪除數(shù)組:
loadedIndex.unshift(index);
}
});
// 刪除已處理的對(duì)象:
_.each(loadedIndex, function (index) {
lazyImgs.splice(index, 1);
});
}
};
// 綁定事件:
$window.scroll(onScroll);
// 手動(dòng)觸發(fā)一次:
onScroll();
onScroll() 函數(shù)最后要手動(dòng)觸發(fā)一次,因?yàn)轫?yè)面顯示時(shí),并未觸發(fā)scroll事件。如果圖片已經(jīng)在可視區(qū)域內(nèi),這些圖片仍然是loading狀態(tài),需要手動(dòng)觸發(fā)一次,就可以正常顯示。
要測(cè)試圖片懶加載效果,可以在Chrome瀏覽器的控制臺(tái)選擇“Network”,把“Online”改為“Slow 3G”就可以模擬慢速網(wǎng)絡(luò)下瀏覽器懶加載圖片的效果:

|