Javascript 防抖与节流
函数防抖(Debounce)
debounce: 事件触发停止一定时间后才会执行响应的函数,期间如果重复调用动作,重新计算时间。本质上是将多次操作合并为一次操作。可用一个定时器维护,事件触发后wait时间内如果事件重复触发事件,那么取消当前定时器,重新设置一个时延为wait的定时器。
function debounce(fn,wait){
var timer;
return function(){
if(timer){
clearTimeout(timer);
};
var args = Array.prototype.slice.apply(arguments);
timer = setTimeout(function(){
fn.apply(this, args);
},wait);
}
}
还有一种支持立即执行的版本:
function debounce(func, wait, immediate) {
let timer;
return function() {
let context = this;
let args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
var callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, wait)
if (callNow) func.apply(context, args)
} else {
timer = setTimeout(function() {
func.apply(context, args)
}, wait);
}
}
}
函数节流(Throttle)
throttle:事件触发后执行函数在wait时间内事件再次触发,执行函数将不会执行,等规定时间之后事件触发,执行函数方可再次执行。在wait事件内重复执行事件,不重置定时器。
// 实现1
function throttle(fn,wait){
var isExecute = false;
return function(){
var args = Array.prototype.slice.apply(arguments);
if(isExecute) {
return;
}
isExecute = true;
setTimeout(function(){
fn.apply(this,args);
isExecute = false
},wait)
}
}
// 实现2
function throttle(fn,wait){
var lastTime = new Date().getTime();
var firstTime = true;
return function(){
var args = Array.prototype.slice.apply(arguments);
var curTime = new Date().getTime();
if( firstTime ){
firstTime = false;
} else if((curTime - lastTime) < wait){
return;
};
lastTime = curTime;
fn.apply(this,args);
}
}
上述函数返回的是一个函数、不改变原函数。防抖与节流需要调用返回的函数。