1、函數防抖
原理:函數執行過一次後,在等待時間段內不能再次執行。 在等待時間內觸發此函數,則重新計算等待時間。
代碼實現
/*
*fn:要防抖的函數
*wait:要等待的時間
*immediate:是否立刻執行fn函數
*/
function debounce(fn,wait,immediate){
let timer=null;
let _debounce=function(){
//判斷定時器是否存在,存在即刪除定時器
timer&&clearTimeOut(timer);
//是否立刻執行
if(immediate){
//定時器不存在時,纔回去執行函數
!timer&&fn.apply(this,...arruments)
timer=setTimeOut(()={
timer=null;
//過了await時間後,fn纔可以被再次執行
},await)
}else{
timer=setTimeOut(()=>{
//過了await時間後,再次設置的定時器纔不會被清除
timer=null;
fn.apply(this,...arguments);
//arguments爲調用fn函數傳入的參數
},await)
}
}
//取消
_debounce.cancel=()=>{
timer=null;
clearTimeOut(timer);
}
return _debounce;
}
//應用
window.onscroll = _debounce(function(){
console.log(1);
}, 500, true);
應用場景:
- 每次 resize/scroll 觸發統計事件
- 文本輸入驗證(連續輸入文字後發生ajax請求進行驗證,驗證一次就好)
- mousemove,mousedown
- 加載更多
2、函數節流
原理:節流就是在讓函數在特定的時間內只執行一次(持續觸發事件,每隔一段時間,只執行一次事件)。
代碼實現
function throtle(fn,await){
let timer=null;
let previousTime=0;
let _throtle=()=>{
let now=+new Date();//獲取當前時間戳
let remain=now-previousTime
if(remain>await){
//下面的代碼只會在第一次觸發時執行(或者是間隔時間超過await後再次執行)
if(timer){
//清除定時器
clearTimeOut(timer);
timer=null
}
//此時now不等於+new Date()
previousTime=+new Date();//當前時間,使用+獲取當前時間戳
fn.apply(this,...arguments);
}else if(!timer){//避免添加多個定時器
timer=setTimeOut(()=>{
timer=null;
previousTime=+new Date();//當前時間
fn.apply(this,...arguments);
},remain);
}
}
_throtle.cancel=()=>{
timer=null;
clearTimeOut(timer);
previousTime=0;
}
return _throtle;
}
應用場景:
- 每次 resize觸發統計事件
- mousemove