通常在開發商城列表頁,或者相冊的時候會有不少的圖片請求,若是同時所有請求對服務器端的壓力會比較大(不是隻有你一我的),因此就有了圖片的懶加載,懶加載意思就是隻加載可視區域的圖片git
大概思路是這樣子的:github
1.滾動條的高度加上可視區域的高度 > 目標對象距離頂部的高度就意味在可視範圍內。
window.scrollY + window.innerHeight > img.offsetTop
2.img的src屬性使用一個空值,自定義一個屬性data-src綁定真實圖片url
3.當處於可視範圍內的時候src綁定data-src的屬性值
複製代碼
// 基礎版本當在可視範圍內的時候就展現圖片
class lazyLoad {
constructor () {
const imgs = document.getElementsByTagName('img')
// 獲取到的是類數組,須要轉換成數組類型,以便使用數組方法
this.imgs = Array.from([...imgs])
this.init()
}
// 方法一計算高度判斷是否在視口內部
viewImage () {
let height = window.scrollY + window.innerHeight
this.imgs.forEach(img => {
if (img.offsetTop < height) {
const realURL = img.getAttribute('data-src')
// 版本一 爲了表現明顯點加個定時器
setTimeout(() => {
img.src = realURL
}, 200)
}
})
}
init () {
let that = this
// 版本一
window.onscroll = function () {
that.viewImage()
}
}
}
new lazyLoad()
複製代碼
window綁定scroll事件,因爲scoll事件觸發評率極高,影響瀏覽器的性能,因此加一個節流300ms觸發一次數組
// 簡易版節流
function throttle(func, wait) {
var pre = 0
return function() {
var now = new Date()
var context = this
if (now - pre > wait) {
func.apply(context)
pre = now
}
}
}
init () {
let that = this
// 版本一
window.onscroll = throttle(function () {
that.viewImage()
}, 300)
}
複製代碼
IntersectionObserver API能自動監聽目標是否在可視區域內,這樣子就不要判斷高度了;瀏覽器
class lazyLoad {
constructor () {
const imgs = document.getElementsByTagName('img')
this.imgs = imgs
this.init()
}
viewImage () {
// start observing
for (let img of this.imgs) {
const intersectionObserver = new IntersectionObserver(function(entries) {
// If intersectionRatio is 0, the target is out of view
// and we do not need to do anything.
for(let entry of entries) {
if (entry.intersectionRatio <= 0) return
else {
const img = entry.target
const realURL = img.dataset.src
img.src = realURL
}
}
});
// 開始監聽
intersectionObserver.observe(img)
}
}
init () {
this.viewImage()
}
}
new lazyLoad()
複製代碼
IntersectionObserver的介紹,能夠查看文檔服務器
爲了兼容低版本瀏覽器因此要結合兩個版本:app
// 基礎版本當在可視範圍內的時候就展現圖片
class lazyLoad {
constructor () {
const imgs = document.getElementsByTagName('img')
// this.imgs = Array.from([...imgs])
this.imgs = imgs
this.init()
}
// 方法一計算高度判斷是否在視口內部
viewImage2 () {
let windowHeight = window.scrollY + window.innerHeight
this.imgs.forEach(img => {
if (img.offsetTop < windowHeight) {
const realURL = img.getAttribute('data-src')
// 版本一 爲了表現明顯點加個定時器
setTimeout(() => {
img.src = realURL
}, 200)
}
})
}
// 方法二利用API判斷是否在視口內
viewImage () {
// start observing
for (let img of this.imgs) {
const intersectionObserver = new IntersectionObserver(function(entries) {
// If intersectionRatio is 0, the target is out of view
// and we do not need to do anything.
for(let entry of entries) {
if (entry.intersectionRatio <= 0) return
else {
const img = entry.target
const realURL = img.dataset.src
img.src = realURL
}
}
});
intersectionObserver.observe(img)
}
}
init () {
let that = this
// 判斷是否支持IntersectionObserver
if ('IntersectionObserver' in window) {
that.viewImage()
} else {
window.onscroll = throttle(function () {
that.viewImage2()
}, 500)
}
}
}
new lazyLoad()
複製代碼
到此一個簡單版的圖片懶加載就完成了。性能
動動手才能變強吧。ui
源碼地址 github.com/wanghao1993…this