js设计模式之节流器模式

原创
2017/06/20 23:29
阅读数 222

对重复的业务逻辑进行节流控制,执行最后一次操作并取消其他操作,以提高性能,这就是节流模式,即节流器。

下面以图片的延迟加载来演示。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
	<meta charset="utf-8">
	<style>
		#containers div {
			margin-right: 5px;
			border:solid 1px blue;
			padding: 5px;
			float: left;
		}
	</style>
</head>
<body>
 <div id="container"></div>
 <span id="tspan" name="nspan">test</span>
 <script type="text/javascript">
 //节流器
 	var throttle = function(){
 		var isClear = arguments[0],fn;
 		if(typeof isClear === 'boolean'){
 			fn = arguments[1];
 			fn.__throttleID && clearTimeout(fn.__throttleID);//如果计时器句柄存在,则清除计时器
 		} else {
 			fn = isClear;
 			param = arguments[1];
 			var p = extend({
 				context:null,
 				args:[],
 				time:300
 			},param);
 			arguments.callee(true,fn);//清除计时器句柄
 			fn.__throttleID = setTimeout(function(){
 				fn.apply(p.context,p.args)
 			},p.time);
 		}
 	}
 	/**
 	*节流延迟加载类,id为容器id,图片格式:<img src="img/loading.gif" alt="" data-src="img/1.jpg">
 	*/
 	function LazyLoad(id){
 		this.container = document.getElementById(id);
 		this.imgs = this.getImgs();//缓存图片
 		this.init();
 	}
 	LazyLoad.prototype = {
 		init:function(){
 			this.update();
 			this.bindEvent();
 		},
 		getImgs:function(){
 			var arr = [];
 			var imgs = this.container.getElementsByTagName('img');
 			for(var i=0,len=imgs.length;i<len;i++){
 				arr.push(imgs[i]);
 			}
 			return arr;
 		},
 		update:function(){
 			if(!this.imgs.length){
 				return;//如果全部都加载完
 			}
 			var i = this.imgs.length;
 			for(--i;i>=0;i--){
 				if(this.shouldShow(i)){
 					this.imgs[i].src = this.imgs[i].getAttribute("data-src");
 					this.imgs.splice(i,1);//清除缓存的图片
 				}
 			}
 		},
 		shouldShow:function(i){//判断图片是否在可视范围内
 			var img = this.imgs[i],
 			scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
 			scrollBottom = scrollTop+document.documentElement.clientHeight;
 			imgTop = this.pageY(img),
 			imgBottom=imgTop+img.offsetHeight;

 			if(imgBottom>scrollTop&&imgBottom<scrollBottom || (imgTop > scrollTop && imgTop < scrollBottom))return true;
 			return false;
 		},
 		pageY:function(element){//获取页面纵坐标位置
 			if(element.offsetParent){
 				return element.offsetTop+this.pageY(element.offsetParent);
 			} else {
 				return element.offsetTop;
 			}
 		},
 		on:function(element,type,fn){
 			if(element.addEventListener){
 				addEventListener(type,fn,false);
 			} else {
 				element.attachEvent('on'+type,fn,false);
 			}
 		},
 		bindEvent:function(){
 			var that = this;
 			this.on(window,'resize',function(){
 				throttle(that.update,{context:that});
 			});
 			this.on(window,'scroll',function(){
 				throttle(that.update,{context:that});
 			});
 		}
 	}
//使用方法
new LazyLoad('container');
 </script>

</body>

</html>

 

展开阅读全文
加载中

作者的其它热门文章

打赏
0
1 收藏
分享
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部