函數防抖和節流

函數防抖和節流

防抖

對於觸發很是頻繁又沒有必要每次都執行的事件,但願合併到一次去執行;javascript

實現思路:java

事件觸發後,在規定的時間範圍內若是事件重複觸發,那麼忽略以前觸發的事件,而且從新開始計時,直到某一次事件觸發後大於規定時間,咱們才執行須要執行的代碼段(函數);閉包

看起來就像是隻執行了用戶快速操做的最後一次事件;app

  • 代碼實現:
var debounce = function(fn, delayTime) {
 var timeId;
 return function() {    
    var context = this, args = arguments;
       timeId && clearTimeout(timeout);
       timeId = setTimeout(function{
          fn.apply(context, args);
    }, delayTime)
  }
}
  • 簡單分析:

利用閉包保存一個setTimeout的id,若是在delayTime內閉包中的函數再次執行,會馬上clear掉上一次的延時回調,生成一個新的延時回調;若是超過delayTime沒有再次執行閉包中的函數,那延時回調就會被執行,這樣纔算是真正執行了須要執行的事件。函數

  • 應用場景:
  1. 給按鈕加函數防抖防止表單屢次提交。
  2. 對於輸入框連續輸入進行AJAX驗證時,用函數防抖能有效減小請求次數。
  3. 判斷scroll是否滑到底部,滾動事件+函數防抖

節流

對於觸發很是頻繁的事件,在規定時間間隔後才能執行,在規定時間間隔內觸發的事件會被忽略,可是不會從新開始計時post

  • 實現思路:

規定一個時間,一次觸發後,在規定時間內觸發的事件都忽略,超過規定時間後能夠從新執行觸發的事件;this

  • 代碼實現:(兩種)
  1. 時間戳
var throttle = (fn, delayTime) => {
    var _start = Date.now();
    return function() {
        var _now = Date.now(), context = this, args = arguments;
        if(_now - _start >= delayTime) {
              fn.apply(context, args);
               _start = Date.now();
        }
      }
}
  • 簡單分析:

先設定一個初始時間,而後每次執行閉包內的函數都與當前時間作比較,若是小於delayTime,什麼也不作,忽略該次事件,若是大於delayTime,執行回調函數fn,重置初始時間;code

  1. 定時器
var throttle = function(fn, delayTime) {
      var flag;
      return function() {
        var context = this, args = arguments;
        if(!flag) {
            fn.apply(context, args);
              flag = setTimeout(function() {    
                  flag = false;
            }, delayTime);
          }
      }
}
  • 簡單分析:

經過設定一個標誌位,經過標誌位判斷是否能夠執行回調函數,在延時函數中執行回調的同時將標誌位置爲可再次執行,這樣就保證了在規定時間以後能再次執行須要的回調函數;遊戲

  • 應用場景:
  1. 遊戲中的刷新率
  2. DOM元素拖拽
  3. Canvas畫筆功能

防抖和節流區別

  • 防抖是把以前頻繁的事件觸發都放到某一次停頓時觸發,能夠理解爲執行最後一次(並不許確);節流則是執行完一次之後等待一段時間以後才能再次執行,能夠理解爲第一次;這意味着防抖執行的是最新的,而節流在等待中若是事件有更新是不會執行的,會被忽略,這二者應用場景不一樣;
  • 防抖適合屢次事件一次響應的狀況;
  • 節流適合大量事件按時間作平均分配觸發。

參考:事件

十分鐘學會防抖和節流

輕鬆理解JS函數節流和函數防抖

相關文章
相關標籤/搜索