对重复的业务逻辑进行节流控制,执行最后一次操作并取消其他操作,以提高性能,这就是节流模式,即节流器。
下面以图片的延迟加载来演示。
<!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>