防抖和節流

今天遇到一個筆試題,就是有關節流的,今天梳理了一下防抖和節流。等介紹完了就對筆試題進行解答。瀏覽器

問題1: 若是實現了dom拖拽功能,可是在綁定拖拽事件的時候發現每當元素稍微移動一點便觸發了大量的回調函數,致使瀏覽器直接卡死,這個時候怎麼辦?bash

問題2:若是給一個按鈕綁定了表單提交的post事件,可是用戶有些時候在網絡狀況極差的狀況下屢次點擊按鈕形成表單重複提交,如何防止屢次提交的發生?網絡

一、定義

函數防抖(debounce)

當調用動做過 n 毫秒後,纔會執行該動做,若在這 n 毫秒內又調用此動做則將從新計算執行時間
複製代碼

函數節流(throttle)

規定在一個單位時間內,只能觸發一次函數。若是這個單位時間內觸發屢次函數,只有一次生效
複製代碼

二、做用

解決高頻繁問題,既能節省瀏覽器CPU資源,又能讓頁面瀏覽更加順暢,不會由於js的執行而發生卡頓。app

三、兩者的區別

  • 函數防抖只是在最後一次事件後才觸發一次函數;
  • 而函數節流無論事件觸發有多頻繁,都會保證在規定時間內必定會執行一次真正的事件處理函數。

四、使用場景

防抖

  • search搜索,用戶在不斷輸入值時(keyup,keydown),用防抖來節約請求資源。
  • 拖拽、鼠標移動(mousemove)事件
  • window觸發resize的時候,不斷的調整瀏覽器窗口大小,會不斷的觸發這個事件,用防抖來讓其只觸發一次

節流

  • 鼠標不斷點擊觸發,mousedown(單位時間內只觸發一次)
  • 監聽滾動事件,好比是否滑到底部自動加載更多,用throttle來判斷

五、實現

界面實現代碼:dom

<div id='debounce' >
    <h3>這是防抖函數的例子</h3>
    <p>在事件被觸發n秒後再執行回調,若是在這n秒內又被觸發,則從新計時。</p>
    <div style="padding:10px">
          <strong>示例1:</strong>
          <input id="debounceInput" type="text">
    </div>

    <div style="padding:10px">
           <strong>示例2:</strong>
           <div id="debounceCount"></div>
    </div>
 </div>

 <div id='throttle'>
   <h3>這是節流函數的例子</h3>
   <p>規定在一個單位時間內,只能觸發一次函數。若是這個單位時間內觸發屢次函數,只有一次生效。</p>
   <button id='but' @click='throttleClick'>點擊一下</button>
</div>
複製代碼

防抖js代碼:

var fd = document.getElementById('debounceInput');
  var fdDivCount = document.getElementById('debounceCount');
  var count = 1;
  function outPut() {
    console.log('輸出,', fd.value); 
  }

  function addWhenMove() {
    fdDivCount.innerHTML=count++;
  }

 // 防抖函數
  function _debounce(fun,delayTime) {
     var delayTime = delayTime || 500;
     var timer;
     return function () {
         var that =this;
         var args = arguments;
         if(timer){
              clearTimeout(timer);
         }
         timer = setTimeout(() => {
              fun.apply(that,args)
         }, delayTime);
      }
  }
 fd.addEventListener('keyup', _debounce(outPut, 1000))
 fdDivCount.onmousemove = _debounce(addWhenMove, 1000,true)
複製代碼

運行效果:函數

示例1: post

image

示例2: ui

image

節流js代碼:

new Vue({
       el:'#throttle',
       data:{},
       methods:{
         throttleClick:function (){
            let that = this
            let now = +new Date();
            if (lastTime && lastTime - now < 1000) {
               clearTimeout(timer);
            }
            timer = setTimeout(() => {
               console.log('點擊一下');
               lastTime = +new Date()
            }, 1000);
          }
        }
})
複製代碼

運行效果: this

image

題目描述:spa

現有一個文本輸入框(<input type="text" id="search"/>),當用戶輸入時,500ms輸出(console)一次輸入框的值,請編寫單獨的節流函數throttle,而且實現該功能。 例如:throttle(fn , gapTime)

答案稍後奉上,(#^.^#)

參考連接:juejin.im/post/5b8de8…

相關文章
相關標籤/搜索