目录
需求
工作的时候暂时没有活,所以写个懒加载的踩坑记录。需求就是最平常的图片懒加载,使用一个数组存储所有图片的地址,等到图片出现在可视区域内的时候才去设置其src属性,这样图片才会加载。
思路分析
判断图片是否在可视区域内
这个是最关键的地方,只有正确判断图片中可视区域中才可以正确加载图片。img是图片,parent是其容器,我的具体判断公式如下:
img.offsetHeight + img.offsetTop > parent.scrollTop && img.offsetTop < parent.scrollTop + parent.clientHeight
公式分为两部分。前半部分是判断图片是否能够进入可视区域,后半部分是判断图片是否离开可视区域。其逻辑可以画图捋一下,不再细说。
图片设置
对于一个图片,我们一开始不想加载它,所以用background设置背景图片作为占位。并且,我们还要把它的地址存到它的身上,以便于加载。可以考虑存在元素的dataset中,比如img.dataset.src。这样,对于每个图片,应该做如下设置:
<img data-src="https://acg.toubiec.cn/random.php?1" class="lazy">
这是使用原生HTML写的,如果采用vue等框架可以直接遍历数组地址产生img。还需要给img标签指定类名,我写为lazy。然后给lazy类设置统一样式:
.lazy {
width: 400px;
height: 400px;
background-image: url("https://cn.vuejs.org/images/logo.svg");
background-repeat: no-repeat;
background-size: contain;
margin-bottom: 50px;
}
这里用背景实现占位,background-image就是默认图片。后面如果给图片设置了src,就可以盖住背景了。
父元素设置
我简单使用一个类名为container的div包裹图片:
<div class="container">
<img data-src="https://acg.toubiec.cn/random.php?1" class="lazy">
<img data-src="https://acg.toubiec.cn/random.php?2" class="lazy">
<img data-src="https://acg.toubiec.cn/random.php?3" class="lazy">
<img data-src="https://acg.toubiec.cn/random.php?4" class="lazy">
<img data-src="https://acg.toubiec.cn/random.php?5" class="lazy">
<img data-src="https://acg.toubiec.cn/random.php?6" class="lazy">
</div>
然后给container类设置样式:
.container {
background-color: floralwhite;
width: 60vw;
height: 100%;
overflow-y: auto;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
}
这样,所有图片就是水平居中排列的了。
滚动事件回调函数
要实现懒加载,必须监听滚动事件,在监听函数中判断哪些图片在可视区域,然后加载它。刚刚已经实现了判断图片是否在可视区域的逻辑,现在封装滚动事件的回调函数:
// 判断图片是不是在可视区域内
// parent:父元素 img:图片元素
function ifInview(parent, img) {
return img.offsetHeight &#