1. 程式人生 > 其它 >手寫函式防抖

手寫函式防抖

防抖的定義:

事件響應函式在一段時間後才執行,如果在這段事件內再次呼叫函式,則重新計算執行時間

不防抖的危害:

  1. 傳送過多的請求,伺服器癱瘓
  2. 影響效能,出現卡頓

防抖的應用場景:

  1. scroll 事件滾動觸發
  2. 搜尋框輸入查詢
  3. 表單驗證
  4. 按鈕提交事件
  5. 瀏覽器視窗縮放,resize事件

Underscore

一個JavaScript實用庫,提供了一整套函數語言程式設計的實用功能,裡邊有防抖函式,就是這個哥們_.debounce

<div id="contant"></div>
<button id="btn">取消防抖</button>
<script src="https://cdn.bootcss.com/underscore.js/1.9.1/underscore.js"></script>
<script>
  let count = 0;
  const contant = document.querySelector("#contant");
  function doSomeThing(){
    //可能會做回撥函式或者ajax請求
    contant.innerHTML = count++;
  }
  // 高階函式 防抖
  contant.onmousemove = _.debounce(doSomeThing,1000,false); //第三個引數=>是否立即執行 預設為false
  // 事件響應函式在一段時間後才執行,如果在這段事件內再次呼叫,則重新計算執行時間
  // 當預定的時間內沒有再次呼叫該函式,則執行doSomeThing
</script>

既然都有現成的了,為啥還要手寫防抖函式呢,因為underscore不僅僅包含了防抖函式,還有許多其他的方法,大小有6.5KB(生產版)
如果只是需要underscore裡的debounce防抖函式就引用underscore是不是很浪費,所以直接手寫一個debounce函式,程式碼也不多啦

function debounce(func, wait, immediate){
    let timeout;
    let result;
    let debounced =  function(){
        let context = this;   
        let args = arguments; //event指向
        if(timeout) clearTimeout(timeout);
        if(immediate){
            let callNow = !timeout;
            timeout = setTimeout(()=>{
                timeout = null;
            },wait)
            // 立即執行
            if(callNow) result = func.apply(context, args);
        }else{
            // 不會立即執行
            timeout = setTimeout(function(){
                result = func.apply(context, args);
            }, wait)
        }
        return result;
    }
    debounced.cancel = function() {
        clearTimeout(timeout);
        timeout = null;

    }
    return debounced;
}
//=====================以上是防抖函式=====================
let count = 0;
const contant = document.querySelector("#contant");
const btn = document.querySelector("#btn");
function doSomeThing(e){
    // event指向問題
    console.log(e);
    // 改變執行函式的this指向問題
    console.log(this);
    // 可能會做回撥函式或者ajax請求
    contant.innerHTML = count++;
    // 有return的時候
    return 123;
}
let doSome = debounce(doSomeThing, 10000)

// 取消防抖
// 萬一事件函式執行著,執行著,你不想執行了,10s好漫長,不執行也罷,可以取消防抖哦
btn.onclick = function() {
    doSome.cancel();
}
// 高階函式 防抖
contant.onmousemove = doSome;

當然也可以找到underscore的原始碼,ctrl+c ctrl+v,但是,手敲一遍,會讓你醍醐灌頂,不禁發出 哦~~,原來是這樣