主题
图片懒加载
实现原理:当访问一个页面的时候,先把 img 元素或是其他元素的背景图片路径替换成一张大小为 1*1px 图片的路径(这样就只需请求一次),当图片出现在浏览器的可视区域内时,才设置图片真正的路径,让图片显示出来。
实现方法:先把图片路径放在
data-src
中,到达可视窗口才把它放进src
中
监听滑动,判断是否进入视口
getBoundingClientRect().top
能拿到元素距离可视区域最高边的距离差
js
const imgs = document.getElementsByTagName('img')
function isEntry(e){ // 判断是否进入可视区域
const clientHeight = document.documentElement.clientHeight || document.body.clientHeight
const bound = e.getBoundingClientRect()
return bound.top <= clientHeight
}
function lazyLoadImgs(){ // 进入可视区域的图片进行加载
Array.from(imgs).forEach(img => {
if(isEntry(img)){
img.src = img.getAttribute('data-src')
}
})
}
lazyLoadImgs() // 开始先执行一遍,把在显示区域的图片加载了
window.scroll = function(){
lazyLoadImgs() // 滚动在判断加载,这里感觉可以加个节流去优化
}
IntersectionObserver
js
function lazyLoad(imgs) {
const io = new IntersectionObserver((ioes) => {
// 进入、退出视口的元素
ioes.forEach((ioe) => {
const img = ioe.target
const isIntersectionRatio = ioe.intersectionRatio > 0 && ioe.intersectionRatio <= 1
// 如果是进入视口,且没有 src
if (isIntersectionRatio && !img.src) {
img.src = img.dataset.src
}
img.onerror = img.onload = () => io.unobserve(img)
})
})
imgs.forEach(img => io.observe(img))
}
const imgs = document.getElementsByTagName('img')
lazyLoad(imgs)