<!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>