这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
什么是图片懒加载
随着网页中流媒体的不断增多,网页可能包含的图片也是越来越多,但是这些图片往往需要消耗巨大的流量,所以为了提高网页加载的效率,当用户请求一个网页的时候,并不会一次性把该网页中包含的图片全部发送给用户,而是只发送给用户当前浏览器窗口可视区域内的图片,这就是图片懒加载技术。
如何实现图片懒加载?
方法1:监听scroll事件
通过本方法来实现图片懒加载之前我们需要先知道两个概念即
- 窗口显示区域的高度(window.innerHeight)
- 图片到视窗最上面的距离(getBoundingClientRect().top)
<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); }) 复制代码
思维导图