也写图片延迟加载

去年就开始琢磨着怎么写一个图片延迟加载的组件了,拖到了现在才终于完成了。

参数说明:

  1. placehold {url}占位符,用于替代当前图片的地址;
  2. manual {boolean} 手动模式,默认为false,即自动模式;
  3. dataSrc {string} 放在img标签里的属性,也是img的真实地址;
  4. tops {array} 相对于document的最上方高度;
  5. imgs {array} 需要处理的img元素;
  6. screenH {number} img元素加载时相对于浏览器屏幕的最小值。即tops[i] <= screenH + scrollTop时加载。 默认是当前视图高度的1.5倍。
  7. isHold {boolean}<private>获取screenH 在用户没有提供screenH时,自动出现。

具体的JS代码如下:

window.onload = function(){
	
}


function log(a){
	if(window.console)window.console.log(a);	
	//window.console?window.console.log(a):alert(a);	
}
function mix(s, o, w, pro){
	if(s === undefined || o === undefined)return{};
	w = w || false;
	pro =  pro || false;
	for(var a in o){
		if(typeof a == 'object') mix(s[a], o[a], w, pro);
		if(w)pro? s.prototype[a] = o[a] : s[a] = o[a];
		
		if(!w && !s.hasOwnProperty(a)) {
			s[a] = o[a];
		}
		
	}
}	
/**
 * 图片延迟加载组件
 *@param config {object}
	*@attr placehold {url} 用于替换图片src
	*@attr manual {boolean} default: false 手动模式,默认是自动模式
	*@attr dataSrc {string} default: data-src 存放真实的图片地址
	*@attr tops {array} 所有需要加载的图片相对于body的最上方高度
	*@attr imgs {array} 所有需要加载的图片
	*@attr screenH {number} default: 1.5倍的屏幕高度 图片距离浏览器屏幕上方高度的临界值,小于这个高度就加载。
	*@attr isHold {boolean} <private> 获取screenH 在用户没有提供screenH时,自动出现。
 *@Description:
 *	不适合情况:有js大变动的改变body高度。
 */
function imgLoadLater(o){
	var self = this;
	if(!(self instanceof imgLoadLater)){
		return new imgLoadLater(o);
	}
	config = self._config;
	if(o !== undefined && !o.screenH){
		//config = {};
		config.screenH = self._getScreen();
		config.isHold = true;
	}
	mix(config, o, true);
	self._config = config;
	//log(self._config)
	self._init();
	//return undefined;
}
mix(imgLoadLater , {
	_config: {//配置文件
		//placehold: null,
		manual: false, //手动模式,默认为false 即自动默认
		dataSrc: 'data-src'
		//tops: [],//存放每个元素相对于document的高度值
		//imgs: [],//存放每个img元素
		//screenH: 0//距离浏览器当前屏幕的高度所需的距离
	},
	_getTop: function(elem){
		// 返回元素相对于当前浏览器屏幕顶部的高度
		return elem.getBoundingClientRect().top;
	},
	_imgLoad: function(){
		var self = this,
			config = self._config,
			imgs = config.imgs || [],
			tops = config.tops || [],
			dataSrc = config.dataSrc,
			l = imgs.length,
			winH = config.screenH + self._getScrollTop(),
			arrImgs=[],
			arrTops=[];
		if(l < 1) return;
		for(var i=0; i < l; i++){
			//log(tops[i]+ ' '+winH);
			if(tops[i] <= winH){
				imgs[i].src = imgs[i].getAttribute(dataSrc);
				//log(i);
			}else{
				arrImgs.push(imgs[i]);
				arrTops.push(tops[i]);
			}
		}
		//log(arrTops);
		self._config.imgs = arrImgs;
		self._config.tops = arrTops;
	},
	_getScreen: function(){
		//
		return document.documentElement.clientHeight * 1.1;
	},
	_getScrollTop: function(){
    return Math.max(document.body.scrollTop, document.documentElement.scrollTop);
	},
	_filterImg: function(){
		var config = this._config,
			tops = config.tops || [],
			imgs = config.imgs || [],
			dataSrc = config.dataSrc,
			placehold = config.placehold,
			scrollTop = this._getScrollTop(),
			winH = config.screenH + scrollTop,
			arrImgs = document.getElementsByTagName('img'),
			isManual = config.manual,
			i, len, top;
		if(isManual){
			if(imgs.length)arrImgs = imgs;
			else{
				var temp = [];
				for(i=0, len= arrImgs.length; i<len; i++){
					if(arrImgs[i].getAttribute(dataSrc)) temp.push(arrImgs[i]);
				}
				arrImgs = temp;
			}
		}
		
		for(len = arrImgs.length, i = 0; i<len; i++){
			top = this._getTop(arrImgs[i]) + scrollTop;
			if(isManual || top > winH){
				tops.push(top);
				imgs.push(arrImgs[i]);
				if(!isManual) arrImgs[i].setAttribute(dataSrc, arrImgs[i].src);
				placehold === undefined ? arrImgs[i].src = placehold : arrImgs[i].removeAttribute('src');
			}
		}
		this._config.imgs = imgs;
		this._config.tops = tops;
		this._imgLoad();
		this._filterImg = function(){};
	},
	_addEvent: function(elem, type, fn, b){
		if(elem.addEventListener){
			elem.addEventListener(type, fn, b || false);
		}else if(elem.attachEvent){
			elem.attachEvent('on'+type, fn);
		}else{
			elem['on'+type] = fn;
		}
	},
	_removeEvent: function(elem, type, fn){
		if(elem.removeEventListener){
			elem.removeEventListener(type, fn);
		}else if(elem.detachEvent){
			elem.detachEvent('on'+type, fn);
		}
		
	},
	_init: function(){
		var self = this;
		//self._mix(config, o);
		self._filterImg();
		self._addEvent(window, 'scroll', loader);
		self._addEvent(window, 'resize', (resizeLoader = function(){
			if(self._config.isHold) self._config.screenH = self._getScreen();
			setTimeout(function(){ self._imgLoad();}, 100);
		}));


		function loader(){
			self._imgLoad();
			if(self._config.imgs.length == 0){
				self._removeEvent(window, 'scroll', loader);
				self._removeEvent(window, 'resize', resizeLoader);
			}
		}
		
	}
}, true, true);
//log(1);


yss是看过KISSY的数据延迟加载组件后,自己单独写的一个。

)并在KISSY的基础上进行了部分优化,主要体现在tops这个属性上,因为正常情况下,每个图片相对于最上方的高度是不变的,除非出现dom节点的改变操作。这样就节省了每次都去获取当前的img相对于当前浏览器屏幕的高度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值