<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          前端面試系列-JavaScript-防抖與節流(用節流優化防抖)

          2021-3-25    前端達人

          文章目錄

          一.函數防抖

          二、函數節流

          1.時間戳實現

          2.定時器實現

          3.用節流優化防抖(定時器+時間戳)

          三、總結

          四、例子

          一.函數防抖

          當持續觸發事件時,并不執行事件處理函數,一定時間段內沒有再觸發事件,事件處理函數才會執行一次;如果設定的時間到來之前,又一次觸發了事件,就重新開始延時。


          function debounce(fn, delay) {
            // 定時器
            let timer = null
            // 將debounce處理結果當作函數返回
            return function () {
              // 保留調用時的this上下文
              let context = this
              // 保留調用時傳入的參數
              let args = arguments
              // 每次事件被觸發時,都去清除之前的舊定時器
              if(timer) {
                  clearTimeout(timer)
              }
              // 設立新定時器
              timer = setTimeout(function () {
                fn.apply(context, args)
              }, delay)
            }
          }

          二、函數節流

          當持續觸發事件時,保證一定時間段內只調用一次事件處理函數。

          1.時間戳實現


          function throttle(fn, interval) {
                // last為上一次觸發回調的時間
                // 對比時間戳,初始化為0則首次觸發立即執行,初始化為當前時間戳則wait毫秒后觸發才會執行
                let last = 0;
                // 將throttle處理結果當作函數返回
                return function () {
                    // 保留調用時的this上下文
                    let context = this
                    // 保留調用時傳入的參數
                    let args = arguments
                    // 記錄本次觸發回調的時間
                    let now = Date.now();
                    
                    // 判斷上次觸發的時間和本次觸發的時間差是否小于時間間隔的閾值
                    if (now - last >= interval) {
                    // 如果時間間隔大于我們設定的時間間隔閾值,則執行回調
                        last = now;
                        fn.apply(context, args);
                    }
                  }
              }

          定時器實現


          function throttle(fn, wait) {
            let timeout;
            return function() {
              if (!timeout) {
                timeout = setTimeout(() => {
                  timeout = null
                  fn.call(this, arguments)
                }, wait)
              }
            }
          }

          3.用節流優化防抖(定時器+時間戳)
          防抖的問題在于如果用戶的操作十分頻繁——他每次都不等 設置的 delay 時間結束就進行下一次操作,于是每次都為該用戶重新生成定時器,回調函數被延遲了不計其數次。 頻繁的延遲會導致用戶遲遲得不到響應,用戶同樣會產生“這個頁面卡死了”的觀感。

          用節流來優化,保證在一定時間段內會調用一次事件處理函數。

          function throttle(fn, delay) {
                 // last為上一次觸發回調的時間, timer是定時器
                 let last = 0, timer = null
                 // 將throttle處理結果當作函數返回
                 
                 return function () { 
                   // 保留調用時的this上下文
                   let context = this
                   // 保留調用時傳入的參數
                   let args = arguments
                   // 記錄本次觸發回調的時間
                   let now = +new Date()
                  // +是一元操作符,利用js隱式轉換將其他類型變為數字類型
                   
                   // 判斷上次觸發的時間和本次觸發的時間差是否小于時間間隔的閾值
                   if (now - last < delay) {
                   // 如果時間間隔小于我們設定的時間間隔閾值,則為本次觸發操作設立一個新的定時器
                      clearTimeout(timer)
                      timer = setTimeout(function () {
                         last = now
                         fn.apply(context, args)
                       }, delay)
                   } else {
                       // 如果時間間隔超出了我們設定的時間間隔閾值,那就不等了,無論如何要反饋給用戶一次響應
                       last = now
                       fn.apply(context, args)
                   }
                 }
               }

          三、總結
          函數防抖:將幾次操作合并為一此操作進行。原理是維護一個計時器,規定在delay時間后觸發函數,但是在delay時間內再次觸發的話,就會取消之前的計時器而重新設置。這樣一來,只有最后一次操作能被觸發。
          函數節流:使得一定時間內只觸發一次函數。原理是通過判斷是否到達一定時間來觸發函數。
          區別: 函數節流不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數,而函數防抖只是在最后一次事件后才觸發一次函數。
          場景:比如在頁面的無限加載場景下,我們需要用戶在滾動頁面時,每隔一段時間發一次 Ajax 請求,而不是在用戶停下滾動頁面操作時才去請求數據。這樣的場景,就適合用節流技術來實現。


          轉自:csdn 

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合