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);
}
}
上述函數返回的是一個函數、不改變原函數。防抖與節流需要調用返回的函數。