一、使用场景
图片懒加载,就是图片的延时加载,通过先加载用户可视区域内的图片,延时加载出其他不可视的图片,来进行优化。
可通过禁止缓存和将网络切换至3G,模拟网络状况不佳的情况
二、scroll事件监听实现
监听鼠标滚动事件,鼠标滚动就触发,当图片到图片到显示区的距离小于显示区高度时,及getBoundingClientRect().top
小于window.innerHeight
,优先加载该图片。
浏览器没有滚动到图片所在位置时,图片是不需要被加载的,所以可以使用自定义属性(data-*
),浏览器碰到自定义属性时是无法处理的。所以我们将图片所在的路径保存在自定义属性中,这样浏览器拿不到图片路径就加载不出图片。
我们只需要对在页面滚动的时候对所有的图片做一个判断,当图片在显示区域出现时,将自定义属性中的图片路径赋值给src
,这样浏览器拿到路径就可以显示该图片。对应的js代码如下
const images = document.querySelectorAll('img')
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触发');
})
})
利用事件监听来实现图片懒加载存在一定的缺陷,①需要滚动才能够触发事件,也就是说当页面没有滚动的时候,一张图片都加载不出来,即使图片已经在显示区域内,②当页面内容很少,不需要滚动时,事件永远不会触发,图片永远加载不出来,③当图片加载出来后,仍可触发滚动事件,浪费了资源。
三、IntersectionObserver实现
IntersectionOberver
是浏览器提供的构造函数,它可以对浏览器内的元素进行观察,其参数中的一个为回调函数,当看见目标元素与看不见目标元素时都会触发一次回调函数,此回调函数的返回值是一个数组。js代码如下
//通过IntersectionObserver实现
//回调函数返回的是一个数组,其中isIntersecting记录了当前图片是否能够看到
const callback = entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
//当能够看到图片时,利用target获取目标元素也就是图片
const image = entry.target;
const data_src = image.getAttribute('data-src')
image.setAttribute('src', data_src)
//图片加载完成,就停止对该图片的观察
observer.unobserve(image);
console.log('触发');
}
})
}
const observer = new IntersectionObserver(callback);
images.forEach(image => {
//观察每一个图片
observer.observe(image);
})
因为利用了IntersectionObserver
中返回数组里的isIntersecting
值,所以可以在一开时便判断图片是否可以看见,并作出加载,也就不存在利用事件监听实现中所产生的缺点,并且在图片加载完成后便停止对该图片的观察,所以也不需要担心资源的浪费。