Appearance
如何实现图片懒加载
思路及实现
- 加载loading图片
- 判断哪些图片要加载(滚动条以上scrollTop+当前内容clientHeight)
- 替换真图片(将data-src中的值给到src,进行请求图片)
方案一: getBoundingClientRect()
Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。
示例代码
js
// 定义图片懒加载处理函数
function mapImagesAndTryLoad() {
// 获取所有含有 data-src属性的img标签
const images = document.querySelectorAll('img[data-src]')
if(images.length === 0) return
images.forEach(img => {
const rect = img.getBoundingClientRect()
// 如果图片露出来 在视图范围内
if(rect.top < window.innerHeight) {
img.src = img.dataset.src
// 移除 data-src属性,减少下次计算成本
img.removeAttribute('data-src')
}
})
}
// "_.throttle()" 使用 节流提高性能
window.addEventListener('scroll', _.throttle(() => {
mapImagesAndTryLoad()
}, 100))
// 初始执行一次
mapImagesAndTryLoad()
方案二: IntersectionObserver API
IntersectionObserver API,一个能够监听元素是否到了当前视口的事件 entry.isIntersecting 代表目标元素可见
示例代码
js
const intersectionObserver = new IntersectionObserver((changes) => {
// changes 目标集合
changes.forEach(change => {
// 判断元素是否在可见区域内
if(change.isIntersectiong) {
const img = change.target
img.src = img.dataset.src
// 停止监听
intersectionObserver.unobserve(img)
}
})
})
function mapImagesAndTryLoad() {
const images = document.querySelectorAll('img[data-src]')
images.forEach(img => {
// 开始监听目标元素
intersectionObserver.observe(img)
})
}
mapImagesAndTryLoad()
方案三 LazyLoading 属性
html
<img src="shanyue.jpg" loading="lazy" />