《JavaScript高级程序设计》中有专门应对此问题的函数节流
function throttle(method, context) {
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call(context);
}, 500);
}
利用定时器,让函数执行延迟500毫秒,在500毫秒内如果有函数又被调用则删除上一次调用,这次调用500毫秒后执行,如此往复。代码可以改为
n = 0;
function resizehandler() {
console.log(new Date().getTime());
console.log(++n);
}
function throttle(method,context) {
clearTimeout(method.tId);
method.tId = setTimeout(function() {
method.call(context);
},500);
}
window.onresize = function() {
throttle(resizehandler,window);
};
另一种做法
function throttle(method,delay) {
var timer = null;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
method.apply(context,args);
}, delay);
}
}
调用一下试试,一样的效果
<script type="text/javascript">
n = 0;
function resizehandler() {
console.log(new Date().getTime());
console.log(++n);
}
function throttle(method,delay) {
var timer = null;
return function() {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function() {
method.apply(context,args);
}, delay);
}
}
// 因为返回函数句柄,不用包装函数了
window.onresize = throttle(resizehandler, 500);
</script>
两种方法都是利用了setTimeout,不同的是第二种方法加入的函数延迟执行时间,这个在第一种方案中很容易也具有此功能,加一个参数的事儿。
但第一种方案把tId设为函数的一个变量保存,而第二种创建了一个闭包来存储。
网友评论