基于原生js的图片延迟加载

时间:2021-12-22 01:47:20

当页面图片比较多的时候,我们通常会做一个延迟加载,避免页面打开时一下子的请求数太多,加载过慢影响用户体验。

如果项目用了jquery框架,则可以直接用 jquery.lazyload.可在jquery官网下载到。

如果项目是基于原生js的,可以参考以下:

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>lazyload class</title>
<style>
img{width:auto; height:300px;}
</style>
</head>
<body>
<h1>测试图片延迟加载效果</h1>
<p><img data-url="images/p1.jpg" src="data:images/grey.gif" alt="p1"></p>
<p><img data-url="images/p2.jpg" src="data:images/grey.gif" alt="p2"></p>
<p><img data-url="images/p3.jpg" src="data:images/grey.gif" alt="p3"></p>
<p><img data-url="images/p4.jpg" src="data:images/grey.gif" alt="p4"></p>
<p><img data-url="images/p5.jpg" src="data:images/grey.gif" alt="p5"></p>
<p><img data-url="images/p6.jpg" src="data:images/grey.gif" alt="p6"></p>
<script>
var API = {
on : function(ele, ev, handler){
ele.addEventListener ? ele.addEventListener(ev, handler) : ele.attachEvent('on' + ev, handler);
return ele;
},
bind: function(obj, handler){
return function(){ handler.apply(obj,arguments); }
},
pageX: function(ele){
var left = 0;
do{
left += ele.offsetLeft;
}while(ele.offsetParent && (ele = ele.offsetParent).className.toLowerCase() !=='body');
return left;
},
pageY: function(ele){
var top = 0;
do{
top += ele.offsetTop;
}while(ele.offsetParent && (ele = ele.offsetParent).className.toLowerCase() !=='body');
return top;
},
hasClass: function(ele,cls){
return new RegExp('^|\\s' + cls + '\\s|$').test(ele.className);
},
attr: function(ele,attr,val){
if(val===undefined){
return ele.getAttribute(attr);
}else{
return ele.setAttribute(attr, val);
}
}
}; function Lazyload(id, diff, attr){
this.container = typeof id === 'string' ? document.getElementById(id) : document.body;
this.imgs = [].slice.call(this.container.getElementsByTagName('img'));
this.diff = diff || 0;
this.attr = attr || "data-url";
this.load();//尝试加载正处在视窗中的图片
this.spyScroll();
} Lazyload.prototype = {
constructor: Lazyload,
spyScroll: function(){
API.on(window, 'scroll', API.bind(this, this.load) );
},
load: function(){
if(!this.imgs.length) return; //all image loaded
var pos,url,imgs = this.imgs.slice();//copy the array
var c=0;
for(var i = 0, len = imgs.length; i < len; i++){
pos = this.pos2viewport(imgs[i]);
if(pos === 'above' || pos === 'in'){ //console.log(imgs[i],pos,i,' imgs.length=',len);
url = API.attr(imgs[i], this.attr);
API.attr(imgs[i], 'src',url);
API.on(imgs[i], 'load', function(){
this.style.width='auto';//图片加载后 采用图片真实尺寸
this.style.height = 'auto';
});
this.imgs.splice(i-c,1); c++;//保持两数组元素的对应关系
}
}
},
pos2viewport:function(img){//img's position relative to viewport. above, in , below
var imgScrollTop = API.pageY(img), diff = this.diff,
rangeT = imgScrollTop - diff,
rangeB = imgScrollTop + img.clientHeight + diff,
viewportT = document.documentElement.scrollTop || document.body.scrollTop,
viewportB = viewportT + document.documentElement.clientHeight;
var pos = '';
viewportT >= rangeB && (pos = 'above');
viewportB <= rangeT && (pos = 'below');
!pos && (pos = 'in');
return pos;
}
}; var lazy = new Lazyload(document.body, 50);
</script>
</body>
</html>