1. 程式人生 > 實用技巧 >談談js防抖和節流

談談js防抖和節流

常見的防抖節流應用場景:監聽滾動條、輸入框的驗證、echarts自適應處理

如果事件處理沒有頻率限制,就會加重瀏覽器的負擔,影響使用者的體驗感,因此,我們可以採取防抖(debounce)和節流(throttle)來處理,減少呼叫事件的頻率,達到較好的使用者體驗

防抖

當事件被觸發時,設定一個定時器,若期間又被觸發,則重新設定週期,直到週期結束

//需求:監聽瀏覽器滾動事件,返回當前滾條與頂部的距離

//需求實現(未處理版)
  function watchScroll() {
      let scrollTop = document.body.scrollTop || document.documentElement.scrollTop
      console.log(scrollTop)
  }
  window.onscroll = watchScroll

//需求實現(debounce處理版)
//如果不做處理,在拖動滾動條時這個函式觸發的頻率會很高,為了不浪費瀏覽器效能,這裡可以用上防抖函式
  /**
   * @param fn:需要防抖處理的函式,delay:防抖設定的間隔
   * @return function
   */
  function debounce(fn, delay) {
      let timer = null      //這裡用到了閉包,每次onscroll觸發都會呼叫下一行返回的匿名函式,所以timer=null只會執行一次,並且timer會一直保留到閉包函式銷燬為止
      return function () {
          if (timer) {
              clearTimeout(timer)
              timer = setTimeout(fn, delay)
          } else {
              timer = setTimeout(fn, delay)
          }
      }
  }
  function showTop  () {
      let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log(scrollTop);
  }
  window.onscroll = debounce(showTop,1000)
//經過處理,滾動條停止滾動1秒以後,才會打印出滾動條位置

節流

當事件被觸發時,在一定時間內只有第一次觸發有效,若期間又被觸發則無效,直到週期結束

//試試把上述防抖方案用節流來處理
  /**
   * @param fn:需要節流處理的函式,delay:節流設定的間隔
   * @return function
   */
  function throttle(fn, delay) {
      let working = false
      return function () {
          if (working) {
              return false //如果已經設定了定時器且未執行,則不會再次執行到下幾行設定定時器的程式碼
          }
          working = true  //將狀態設定為'執行中'
          setTimeout(function () {
              fn()
              working = false  //定時器內函式執行完畢後將狀態設定為'未執行'
          }, delay)
      }
  }
  function showTop  () {
      let scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    console.log(scrollTop);
  }
  window.onscroll = throttle(showTop,1000)
//上述節流寫法用的是閥門思想,也可以用時間戳來寫,把狀態換成時間戳,然後利用時間戳差值是否大於指定間隔時間來做判定

//經過處理,只有在一直拖著滾動條進行滾動的情況下,會以1s的時間間隔輸出當前位置和頂部的距離,個人認為監聽滾動條這種情景還是用防抖處理比較恰當

因為demo很簡單,無需考慮作用域和引數傳遞,所以上述防抖節流案例沒有用到apply,實際上肯定還要考慮傳遞argument以及上下文環境(this指向)

apply用法 https://blog.csdn.net/qq_21397815/article/details/90482341