js圖片延遲加載(Lazyload)三種實(shí)現(xiàn)方式
延遲加載也稱為惰性加載,即在長(zhǎng)網(wǎng)頁(yè)中延遲加載圖像。
用戶滾動(dòng)到它們之前,視口外的圖像不會(huì)加載。
這與圖像預(yù)加載相反,在長(zhǎng)網(wǎng)頁(yè)上使用延遲加載將使網(wǎng)頁(yè)加載更快。
在某些情況下,它還可以幫助減少服務(wù)器負(fù)載。
延遲加載的優(yōu)點(diǎn):
提升用戶的體驗(yàn),如果圖片數(shù)量較大,打開(kāi)頁(yè)面的時(shí)候要將將頁(yè)面上所有的圖片全部獲取加載,很可能會(huì)出現(xiàn)卡頓現(xiàn)象,影響用戶體驗(yàn)。因此,有選擇性地請(qǐng)求圖片,這樣能明顯減少了服務(wù)器的壓力和流量,也能夠減小瀏覽器的負(fù)擔(dān)。
方法一
將頁(yè)面上所有圖片的src屬性設(shè)置為loading.gif,而圖片的真實(shí)路徑則設(shè)置在data-src屬性中。
當(dāng)頁(yè)面滾動(dòng)的時(shí)候計(jì)算圖片位置和滾動(dòng)的位置,當(dāng)圖片出現(xiàn)在瀏覽器視口內(nèi)時(shí),將圖片的src屬性設(shè)置為data-src的值。
<img src="loading.png" data-src="image.png">
img { display: block; margin-bottom: 50px; }
function lazyload() {
var images = document.getElementsByTagName('img');
var n = 0; // 用于存儲(chǔ)圖片加載到的位置,避免每次都從第一張圖片開(kāi)始遍歷
return function() {
var seeHeight = document.documentElement.clientHeight;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
for(var i = n; i < images.length; i++) {
if (images[i].offsetTop < seeHeight + scrollTop) {
if (images[i].getAttribute('src') === 'loading.png') {
images[i].src = images[i].getAttribute('data-src');
}
n = n + 1;
}
}
}
}
lazyload(); //初始化首頁(yè)的頁(yè)面圖片
window.addEventListener('scroll', lazyload(), false);
方法二
上面的方法雖然沒(méi)什么問(wèn)題,但是性能較差,因?yàn)楫?dāng)頁(yè)面滾動(dòng)時(shí),scroll事件會(huì)高頻觸發(fā),這非常影響瀏覽器性能。
所以,這里要對(duì)lazyload函數(shù)進(jìn)行函數(shù)節(jié)流(throttle)與函數(shù)去抖(debounce)處理。
函數(shù)節(jié)流(throttle)與函數(shù)去抖(debounce)
這里html和css代碼不變,經(jīng)過(guò)throttle處理的js代碼如下:
function throttle (fn, delay, atleast) {
var timeout = null,
startTime = new Date();
return function () {
var curTime = new Date();
clearTimeout(timeout);
if (curTime - startTime >= atleast) {
fn ();
startTime = curTime;
} else {
timeout = setTimeout (fn, delay);
}
}
}
function lazyload() {
var images = document.getElementsByTagName('img'),
n = 0; //存儲(chǔ)圖片加載到的位置,避免每次都從第一張圖片開(kāi)始遍歷
return function() {
var seeHeight = document.documentElement.clientHeight;
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
for(var i = n; i < images.length; i++) {
if(images[i].offsetTop < seeHeight + scrollTop) {
if(images[i].getAttribute('src') === 'loading.png') {
images[i].src = images[i].getAttribute('data-src');
}
n = n + 1;
}
}
}
}
lazyload(); //初始化首頁(yè)的頁(yè)面圖片
window.addEventListener('scroll', throttle(lazyload(), 500, 1000), false);
方法三
目前有一個(gè)新的 IntersectionObserver API,可以自動(dòng)"觀察"元素是否可見(jiàn)。
用這種方法實(shí)現(xiàn)代碼非常簡(jiǎn)潔,但是許多瀏覽器不支持。

- IntersectionObserver 傳入一個(gè)回調(diào)函數(shù),當(dāng)其觀察到元素集合出現(xiàn)時(shí)候,則會(huì)執(zhí)行該函數(shù)。
- io.observe 即要觀察的元素,要一個(gè)個(gè)添加才可以。
- io 管理的是一個(gè)數(shù)組,當(dāng)元素出現(xiàn)或消失的時(shí)候,數(shù)組添加或刪除該元素,并且執(zhí)行該回調(diào)函數(shù)。
function query(selector) {
return Array.from(document.querySelectorAll(selector));
}
var io = new IntersectionObserver(function(items) {
items.forEach(function(item) {
var target = item.target;
if(target.getAttribute('src') == 'loading.png') {
target.src = target.getAttribute('data-src');
}
})
});
query('img').forEach(function(item) {
io.observe(item);
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS/jQuery實(shí)現(xiàn)獲取時(shí)間的方法及常用類完整示例
這篇文章主要介紹了JS/jQuery實(shí)現(xiàn)獲取時(shí)間的方法及常用類,結(jié)合完整實(shí)例形式分析了javascript針對(duì)日期時(shí)間的獲取、轉(zhuǎn)換、計(jì)算與檢測(cè)相關(guān)操作技巧,需要的朋友可以參考下2019-03-03
如何基于filter實(shí)現(xiàn)網(wǎng)站整體變灰功能
這篇文章主要介紹了如何基于filter實(shí)現(xiàn)網(wǎng)站整體變灰功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
javascript中運(yùn)用閉包和自執(zhí)行函數(shù)解決大量的全局變量問(wèn)題
做為一個(gè)javascript新手,為了程式的簡(jiǎn)便,可能會(huì)在javascript中運(yùn)用了大量的全局變量,雖然一時(shí)看來(lái),問(wèn)題解決了,而且也可能讓編碼變得更加的簡(jiǎn)單。2010-12-12
cookie丟失問(wèn)題(認(rèn)證失效) Authentication (用戶驗(yàn)證信息)也會(huì)丟失
window.showModalDialog() 后 window.open() 導(dǎo)致cookie丟失問(wèn)題(認(rèn)證失效) Authentication (用戶驗(yàn)證信息)也會(huì)丟失2009-06-06
基于BootStrap實(shí)現(xiàn)局部刷新分頁(yè)實(shí)例代碼
這篇文章主要介紹了基于BootStrap實(shí)現(xiàn)局部刷新的分頁(yè)的相關(guān)資料,非常不錯(cuò),代碼簡(jiǎn)單易懂,具有參考價(jià)值,需要的朋友可以參考下2016-08-08

