(原创不易,转载请标明出处,谢谢)
应用场景及背景介绍:
某一页面有大量图片。如果一开始全部加载,则同时请求较多的网络资源,页面会出现很长一段时间的空白,用户体验很不好,所以需要图片懒加载。
图片懒加载原理
- 所有图片地址
src
,先设置为某一图片,这样只会请求一次网络资源 - 当所需要的图片进入浏览器窗口视野之后,将图片地址
src
替换为真实的图片地址。
演示效果
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
.wrap{
width: 800px;
margin: auto;
display: flex;
flex-wrap: wrap;
}
.wrap img{
width: 50%;
height: auto;
}
</style>
</head>
<body>
<div class="wrap">
</div>
<script>
let imgs = [
"http://seopic.699pic.com/photo/50156/2840.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50148/0957.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50146/0835.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50021/1012.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50127/5145.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50122/4249.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50041/6637.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50085/0650.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50120/4383.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50035/4345.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50119/3443.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50075/8488.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50087/0693.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50154/8480.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50063/0660.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50046/2788.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50070/7820.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50025/5275.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50025/1819.jpg_wh1200.jpg",
"http://seopic.699pic.com/photo/50036/1958.jpg_wh1200.jpg"
];
let wh = window.innerHeight;
let img = new Image();
img.src = 'http://img.zcool.cn/community/011546554b9ab1000001bf729a84ca.jpg';
img.onload = function(){ // 预置的这张图片,必须加载完才能进行下面的操作
renderImgArr();
renderRealImg();
}
window.addEventListener('scroll',()=>{ // 添加监听事件
renderRealImg();
});
function renderImgArr(){ // 渲染dom,且将所有图片的src,都先设置为 预置的图片
let nodelist = []
for(i in imgs){
let tmp = `<img class='eimg' src='http://img.zcool.cn/community/011546554b9ab1000001bf729a84ca.jpg' data-src='`+ imgs[i] +`' />`;
nodelist.push(tmp);
}
let _html = nodelist.join('');
let wrap = document.getElementsByClassName('wrap')[0];
wrap.innerHTML = _html;
}
function renderRealImg(){ // 渲染真实图片
let imgNodes = g('.eimg');
for(let i = 0 ; i < imgNodes.length; i++){
// 先检测有没有已被加载的属性
if(!imgNodes[i].getAttribute('loaded')){ // 如果已经被设置成真实图片,则不必重复加载
// 再检测到窗口的位置
if(wh>= (imgNodes[i].offsetTop - window.pageYOffset)){ // 图片到窗口顶端的距离,小于整个窗口的高度,即这张图出现在窗口视野内。
imgNodes[i].setAttribute('src',imgNodes[i].getAttribute('data-src'));
imgNodes[i].setAttribute('loaded',true);
}else{ // 如果此张图片没有在窗口视野内,那么这张图片之后的图片肯定也不在视野内,所以跳出循环,不必对之后的图片进行检测。
break;
}
}
}
}
function g(s){ // .a 或者 #a
// 以.开头还是以#开头
let method = /\./.test(s) ? 'getElementsByClassName' : 'getElementById';
return document[method](s.substr(1));
}
</script>
</body>
</html>