函數節流與函數防抖

最近經常看到“函數節流”與“函數防抖”,於是便總結了一篇文章

出現原因

某些事件,如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函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章