如何实现图片懒加载
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>图片懒加载</title> </head> <style> * { margin: 0; padding: 0; } .lazyload-img { display: block; width: 600px; height: 400px; margin: 50px; } </style> <body> <div class="wrap"> <!-- 使用一张默认图片占位,在标签上设置一个自定义的data-url属性,该属性的值存放着图片的真实请求地址,图片进入可视区域之后,获取img标签上的data-url属性的值,把它设置到src属性上 --> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/live/2023/02/21/7994c524a88742858660825de9d3c01d.png"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/goods/2022/12/05/c82d2a5322034564b25544b9bcf3bbd8.png"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/goods/2022/11/21/60ec30da96de4ca7bcb235e8aece12c0.jpg"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/goods/2022/11/16/a2b85d311e764247a3f8f104f84ea2f0.jpg"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/goods/2022/11/16/880ea15b19db4d4eb5670df1195721d8.jpg"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/goods/2022/11/16/2f4468ae63e74696a9b9b4e1e3f2ee7f.jpg"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/goods/2022/11/16/bb8e5cfab51e4be3845c500ee3aad653.jpg"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/live/2022/09/02/a66ff27fba3e49f1ac0f0ecbfd3eaed9.png"> <img src="https://www.yswx.cn/upload/202204/12/202204121846289521.jpg" class="lazyload-img" data-url="https://oss.lingjiang.com/images/live/2022/08/23/378dabc2872e41ca90666502fce78bb7.png"> </div> </body> </html> <script> /** * @title 图片懒加载 * @principle 原理:当图片进入到可视区时,再真正加载图片 * @meaning 好处:减少无效资源加载,减少页面http请求,提高页面加载速度,优化用户体验 * @returns */ // 获取当前文档流的根节点,用于获取当前窗口的高度(clientHeight)和宽度(clientWidth),便于判断图片是否在可视区内 let rootElement = document.documentElement; // 获取所有img标签,并转化为数组 let arrImgList = Array.from(document.querySelectorAll('.lazyload-img')); // 封装一个方法判断某一个元素是否在可视区域 function fnIsVisible(element) { // getBoundingClientRect: 所有的元素节点上都有这个方法,提供当前元素节点的大小、位置等信息,就是 CSS 盒状模型的所有信息。 let rect = element.getBoundingClientRect(); console.log(rect) // 节点距离顶部的位置小于窗口高度、距离窗口底部的位置大于0、距离左侧的位置小于窗口宽度、距离窗口右侧的位置大于0,那么就可以证明该节点在可视区范围内 return rect.top < rootElement.clientHeight && rect.bottom > 0 && rect.left < rootElement.clientWidth && rect.right > 0; } // 封装一个方法,动态设置img标签的scr属性 function fnLoadImg() { for (let i = 0; i < arrImgList.length; i++) { let img = arrImgList[i]; // 如果在可视区,设置scr属性 if (fnIsVisible(img)) { img.src = img.getAttribute('data-url'); // 图片加载后,下次就不用在设置了,直接将此节点移除 arrImgList.splice(i, 1); i--; } } } // 一开始先执行一次,把在第一次进入页面时在可视区域的图片加载出来 fnLoadImg(); // 监听滚动事件,频繁判断图片是否进入到可视区 let timer = null; // 性能优化,防抖 document.addEventListener('scroll', () => { // 防抖处理 if (timer) clearTimeout(timer); timer = setTimeout(() => { // 页面滚动的时候,不断有新的图片进入可视区域,此时再调用lazyloadImg函数 fnLoadImg(); }, 100); }) /** * 面试回答 * 1.首先获取根节点 通过clientHeight和clientWidth获取窗口宽度和高度 * 2.在获取所有图片标签集合,并转换为数组 * 3.封装一个方法,该方法用于循环数组并通过 getBoundingClientRect 方法获取到节点位置,与窗口宽度高度做对比,进而判断出图片是否在可视区范围内,如果在可视区内,就设置img的src属性 * 3.监听滚动事件,触发滚动事件,就重复调用上述方法,从而实现图片懒加载。(监听滚动事件,采用防抖,优化性能) */ </script>