实现方案
- 默认不加载图片,仅加载占位图片
- 计算图片是否位于可视区域内,触发加载条件
- < img >src属性加载资源
在计算图片是否位于可视区域时,需要先了解
- scollTop/offsetTop等,这篇博客有对这些偏移量的详细解释
- 判断方法:可视区域的高度(offsetHeight) + 滚动条卷去的高度(scrollTop) >= 元素相对于外框的距离(offsetTop) - 偏移量 (提前加载)
代码实现
html:
<style type="text/css">
.container{
width:200px;
height:200px;
position:relative;
overflow-y:scroll;
}
.img-area{
width:100px;
height:100px;
}
</style>
<div class="container">
<div class="img-area">
<img class="pic" alt="loading" data-src="./img/img1.png" src="占位图片">
</div>
<div class="img-area">
<img class="pic" alt="loading" data-src="./img/img2.png" src="占位图片">
</div>
<div class="img-area">
<img class="pic" alt="loading" data-src="./img/img3.png" src="占位图片">
</div>
<div class="img-area">
<img class="pic" alt="loading" data-src="./img/img4.png" src="占位图片">
</div>
<div class="img-area">
<img class="pic" alt="loading" data-src="./img/img5.png" src="占位图片">
</div>
</div>
data-src是自定义属性,保存图片的真实地址,src是占位图片的地址
js:
var container = document.querySelector('.container');
container.onscroll = function(){
checkImgs();
}
function isInSight(el) {
var sTop = container.scrollTop;
var oHeight = container.offsetHeight;
var oTop = el.offsetTop;
return sTop + oHeight > oTop;
}
function checkImgs() {
var imgs = document.querySelectorAll('.pic');
Array.from(imgs).forEach(el => {
if (isInSight(el)) {
loadImg(el);
}
})
}
function loadImg(el) {
var source = el.dataset.src;
el.src = source;
}
checkImgs();
待优化部分:
- onscroll会多次触发回调函数,应设置节流函数
- 在计算时,增加偏移数据,提前加载图片,提升用户体验
其他思路
- 使用IntersectionObserver(html5 API)
- 利用分页(底部loading标签)