这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
什么是图片懒加载
随着网页中流媒体的不断增多,网页可能包含的图片也是越来越多,但是这些图片往往需要消耗巨大的流量,所以为了提高网页加载的效率,当用户请求一个网页的时候,并不会一次性把该网页中包含的图片全部发送给用户,而是只发送给用户当前浏览器窗口可视区域内的图片,这就是图片懒加载技术。
如何实现图片懒加载?
方法1:监听scroll事件
通过本方法来实现图片懒加载之前我们需要先知道两个概念即
- 窗口显示区域的高度(window.innerHeight)
- 图片到视窗最上面的距离(getBoundingClientRect().top)
通过给图片的src属性名设置为自定义属性data-src使得为滚动到图片时不加载图片
<img data-src="./CSS.png" alt="">
<img data-src="./Debug.png" alt="">
<img data-src="./Flex布局.png" alt="">
实现代码
// 获取所有图片的DOM节点
const images = document.querySelectorAll('img');
// 监听scroll事件,并计算每一个图片距离视窗顶部的高度和视窗高度的关系
window.addEventListener('scroll',(e) => {
images.forEach(image => {
// 获取图片距离浏览器视窗顶部的高度
const imageTop = image.getBoundingClientRect().top;
if (imageTop < window.innerHeight) {
const data_src = image.getAttribute('data-src');
image.setAttribute('src',data_src);
}
console.log('scroll触发');
})
})
存在的问题
只要浏览器监听到滚动变化,就会不断触发调用,严重影响性能。
方法2:通过IntersectionObserver(交叉观察)(推荐使用)
这个API指的是当视窗和目标对象发生交集的时候调用。
详细思路代码版
// 获取所有图片的DOM节点
const images = document.querySelectorAll('img');
// 观察函数的回调函数在观察到的时候触发一次,观察不到再触发一次
callback = (entries) => {
// 这个entries参数是绑定好的所有元素数组
// 如果某个元素被观察到了则修改属性,加载图片,然后取消观察,因为已经加载出来了
entries.forEach(entry => {
if (entry.isIntersecting) {
const image = entry.target;
const data_src = image.getAttribute('data-src');
image.setAttribute('src',data_src);
observer.unobserve(image);
console.log('触发单个观察');
}
})
}
// 构造IntersectionObserver函数
const observer = new IntersectionObserver(callback);
// 给每一张图片绑定观察函数
images.forEach(image => {
observer.observe(image);
})