技术原理简介:
用户访问页面很多时候,并没有滚动到底部,所以有时候很多图片载入却是浪费了时间
将需要被动加载的图片的src属性用自定义属性写入HTML,src指向一个1像素宽高的占位图片
根据滚动条位置和图片坐标计算判断图片是否出现在可视区域内,如果是,那么加载图片
技术的好处:
1,加快页面载入速度,提高用户体验,首页图片较多的页面尤其明显
2,节省流量和服务器连接数
/**
* Javascript Image Delay load
*
* Javascript实现的页面图片被动加载类,在使用前用1像素图像进行占位
* 并给img tag 添加 自定义bigsrc属性 ,当有图片进入可视区域内时,载入图片
* 提高页面载入速度,节省不必要的流量和连接数
*
* @TODO x轴滚动加载功能未被实现
*/
//闭包防止变量冲突
(function(){
//预定义变量,减小代码体积
var _ = document,
A = _.compatMode,
B = _.body,
C = _.documentElement;
//Constructor
function AimoLoad(e){
//要处理的包含延迟加载图片的容器
this.area = e ? this.get(e) : _;
//需要延迟加载的所有图片对象
this.imgs = [];
//执行判断 条件成立 载入图片
this.run();
}
//扩展原型链(注册类其他方法)
AimoLoad.prototype = {
//获取DOM元素,仅支持ID
'get' : function(e){
return typeof(e)=='string' ? _.getElementById(e) : e;
},
//获取所有需要被动载入的图片集合
'getImages' : function(){
var i = 0,
imgs = this.area.getElementsByTagName('img'),
l = imgs.length;
for ( ; i < l; i++) {
//过滤带有bigsrc属性的所有图片
if(imgs[i].getAttribute('bigsrc')){
this.imgs.push(imgs[i]);
}
}
},
//获取元素位置坐标
'getPosition' : function(el){
var x = 0, y = 0;;
if (el.getBoundingClientRect) {
var box = el.getBoundingClientRect(),
el = (A != "CSS1Compat") ?
_.body : C;
x = box.left + el.scrollLeft - el.clientLeft;
y = box.top + el.scrollTop - el.clientTop;
} else {
x = el.offsetLeft;
y = el.offsetTop;
var parent = el.offsetParent;
while (parent) {
x += parent.offsetLeft;
y += parent.offsetTop;
parent = parent.offsetParent;
}
}
return {'x' : x, 'y' : y};
},
//封装判断变量是否定义
'defined' : function(o){
return (typeof(o)!="undefined");
},
//封装合法化Int变量
'zeroFix' : function(n){
return (!this.defined(n) || isNaN(n))? 0 : n;
},
//获取可视部分高度
'getVisibileHeight' : function(){
var cm = C && (!A || A=="CSS1Compat");
if (!window.opera && cm) {
return C.clientHeight;
}else if (A && !window.opera && B) {
return B.clientHeight;
}
return this.zeroFix(self.innerHeight);
},
//获取垂直滚动条位置
'getScrollTop' : function(){
if (C && this.defined(C.scrollTop) && C.scrollTop>0) {
return C.scrollTop;
}
if (B && this.defined(B.scrollTop)) {
return B.scrollTop;
}
return 0;
},
//执行主函数
'run' : function(){
//获取其他脚本注册到window上的onscroll和onresize事件,避免冲突
var _resize = window.onresize || function(){},
_scroll = window.onscroll || function(){},
//引用自身,另存this指向
_self = this,
//定义注册函数
delayLoad = function(){
//清空前一次获取的所有图片
_self.imgs = [];
//获取当前未载入的图片
_self.getImages();
//如果已经没有被动载入的图片了,那么释放注册的事件,提高性能,节省内存
if(_self.imgs.length==0){
window.onscroll = function(){
_scroll();
};
window.onresize = function(){
_resize();
};
//alert('清除事件');
return;
}
var i = 0,
m = _self.imgs,
l = _self.imgs.length,
y = _self.getVisibileHeight(),
t = _self.getScrollTop();
//遍历所有需要被动载入的图片
for( ; i < l; i++){
//闭包保证i变量
(function(i){
//获取每个图像对象的坐标
var pos = _self.getPosition(m[i]);
//如果图片出现在可视区域内
if(t + y > pos.y){
//读取bigsrc属性,替换当前src属性
m[i].setAttribute('src', m[i].getAttribute('bigsrc'));
//删除bigsrc属性,提高性能
m[i].removeAttribute('bigsrc');
}
})(i);//闭包结束
}//循环结束
};//定义注册函数结束
//注册函数到window scroll事件
window.onscroll = function(){
_scroll();//执行其他脚本注册到当前事件的函数
delayLoad();
};
//注册函数到window resize事件
window.onresize = function(){
_resize();//执行其他脚本注册到当前事件的函数
delayLoad();
};
}
}
//暴露接口到外部,以便调用
window.AimoLoad = AimoLoad;
})();