最近經常看到“函數節流”與“函數防抖”,於是便總結了一篇文章
出現原因
某些事件,如mousemove、scroll等是會不斷觸發,如果對應處理函數中有執行DOM操作、加載資源的行爲,那很有可能會導致瀏覽器卡頓、崩潰等
目前主流的解決方法爲函數節流與函數防抖
函數節流
思想
當調用動作過n毫秒後,纔會執行該動作,若在這n毫秒內又調用此動作則將重新計算執行時間
操作
1.第一次調用函數,創建一個定時器,在指定的時間間隔之後運行代碼
2.當第二次調用該函數時,清除前一次的定時器並重新設置
3.如果前一個定時器已經執行過了,清除操作並不會產生什麼影響
4.如果前一個定時器尚未執行,上述操作就是將其替換爲一個新的定時器
/* 一個封裝節流操作的函數
method參數爲實際執行的函數
args爲要傳遞的參數數組
contex參數爲執行環境 */
function throttle(method,args,context){
clearTimeout(method.tId);
method.tId=setTimeout(function(){
method.apply(context,args);
},200);
}
function move(){
console.log("xxx")
}
document.querySelector("#target").onmousemove=function(){
throttle(move);
}
如果我們不進行節流,那麼鼠標在target元素上做一次滑行就會執行多次move函數,而節流後move函數執行數量明顯變少
侷限
如果鼠標一直滑動,那麼move方法永遠不會執行,這時候就需要函數防抖
函數防抖
思想
預先設定一個執行週期,當調用動作的時刻大於等於執行週期則執行該動作,在這段事件內新的調用動作都將無效,然後進入下一個新週期
操作
/* 一個封裝節流操作的函數
method參數爲實際執行的函數
wait參數爲時間間隔
args爲要傳遞的參數數組
contex參數爲執行環境 */
function debounce(method,wait,args,context){
if(!method.start){
method.start=new Date();
}
var now=new Date();
if(now-method.start>=wait){
method.apply(context,args);
method.start=now;
}
}
document.querySelector("#target").onmousemove=function(){
debounce(move,2000);
}
採用函數防抖後,只要鼠標在target上滑動,每2秒執行一次move函數