對防抖和節流的理解及其應用場景


在開發中,我們常常會去監聽滾動事件或者用戶輸入框驗證事件,如果事件處理沒有頻率限制,就會加重瀏覽器的負擔,影響用戶的體驗感,

因此,我們可以采取防抖(debounce)和節流(throttle)來處理,減少調用事件的頻率,達到較好的用戶體驗。

防抖(debounce):

  在事件被觸發n秒后再執行回調,如果在這n秒內又被觸發,則重新計時,重新出發定時器。
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .box {
      width: 200px;
      height: 200px;
      overflow: auto;
    }
  </style>
</head>
<body>
  <div class="box" id="container">
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
    <p>防抖演示</p>
  </div>
</body>
function debounce(fn, wait) {
  var timeout = null;// 使用閉包,緩存變量
  return function() {
        if(timeout !== null) {
          console.log('清除定時器啦')
          clearTimeout(timeout);  //清除這個定時器
        }
        timeout = setTimeout(fn, wait);
    }
  }
  // 處理函數
  function handle() {
      console.log(Math.random());
  }
  var container = document.getElementById('container')
  container.addEventListener('scroll', debounce(handle, 1000));

 

 

我們可以發現,當連續觸發scroll事件,handle函數只會在1秒時間內執行一次,在如果繼續滾動執行,就會清除定時器,重新計時。相當於就是多次執行,只執行一次。

 

節流(throttle):

  規定在一個單位時間內,只能觸發一次函數。如果這個單位時間內觸發多次函數,只有一次生效。
var throttle = function(func, delay) {
    var timer = null; // 使用閉包,緩存變量
    var prev = Date.now(); // 最開始進入滾動的時間
    return function() {
      var context = this;   // this指向window
      var args = arguments;
      var now = Date.now();
      var remain = delay - (now - prev); // 剩余時間
      clearTimeout(timer);
      // 如果剩余時間小於0,就立刻執行
      if (remain <= 0) {
        func.apply(context, args);
        prev = Date.now();
      } else {
        timer = setTimeout(func, remain);
      }
    }
  }
  function handle() {
      console.log(Math.random());
  }
  var container = document.getElementById('container')
  container.addEventListener('scroll', throttle(handle, 1000));

 

 

在節流函數內部使用開始時間prev、當前時間now和剩余時間remain,當剩余時間小於等於0意味着執行處理函數,這樣保證第一次就能立即執行函數並且每隔delay時間執行一次;

如果還沒到時間,就會在remaining之后觸發,保證最后一次觸發事件也能執行函數,如果在remaining時間內又觸發了滾動事件,那么會取消當前的計數器並計算出新的remaing時間。

通過時間戳定時器的方法,我們實現了第一次立即執行,最后一次也執行,規定時間間隔執行的效果。

 

總結,看完了防抖和節流的分別介紹,我們來看看他們的區別:

  • 函數防抖和函數節流都是防止某一時間頻繁觸發,但是這兩兄弟之間的原理卻不一樣。

  防抖是將多次執行變為只執行一次,節流是將多次執行變為每隔一段時間執行。

 

結合應用場景

  防抖(debounce)

    search搜索聯想,用戶在不斷輸入值時,用防抖來節約請求資源。

    window觸發resize的時候,不斷的調整瀏覽器窗口大小會不斷的觸發這個事件,用防抖來讓其只觸發一次

  節流(throttle)

    鼠標不斷點擊觸發,mousedown(單位時間內只觸發一次)

    監聽滾動事件,比如是否滑到底部自動加載更多,用throttle來判斷


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM