js设计模式之节流器模式

本文介绍了一种利用节流技术实现图片懒加载的方法,通过JavaScript编程实现了滚动监听及图片显示逻辑,有效提升了网页性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

<!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>

 

转载于:https://my.oschina.net/u/2391658/blog/994076

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值