前端 JavaScript 之『防抖』的簡單代碼實現

前戲 🌰

經過上一篇文章的總結,我們知道:短時間內高頻率地觸發事件,可能會導致不良後果。

具體到我們開發界來說,如果數據一致處於一種高頻率更新的狀態,那麼可能會引發的問題如下:

  • 前後端數據交互頻率過高,導致流量浪費。
  • 界面高頻率渲染更新,引發頁面延遲、卡頓或假死等狀況,影響體驗。

在進入正題之前,我們先來看下面這個例子:

<form action="" class="example-form">
    <div>
        <label for="name">名稱</label>
        <input type="text" 
               name="name" 
               id="name" 
               placeholder="please input your name"
         >
    </div>
    <div>
        <label for="res">輸入</label>
        <textarea type="multipart" 
                  name="res" 
                  id="res" 
                  placeholder="這裏是每一次輸入的結果"
        ></textarea>
    </div>
</form>
window.onload = () => {
    const inputEle = document.querySelector("#name");
    const resEle = document.querySelector("#res");
    inputEle.addEventListener("input", function (event) {
        console.log(this.value);
        resEle.value += `\n${ this.value }`
    });
}

頻繁觸發

在輸入框的 input 事件中,將該輸入框的當前值輸出在多行文本框中。可以看到,每輸入一個拼音字母,都會有一條輸出記錄,觸發頻率取決於人的打字速度。

新需求 🤬

假如,現在有這麼一個新需求,要我們在 input 事件中加入新的邏輯:將輸入框的當前值發往後臺進行存儲。

可以想象,這種情況下的前後端交互頻率該有多高,其中很多數據都是沒有必要即刻發送保存的,純屬浪費流量。

我們可以考慮對這個需求進行一下優化,只要控制一下交互頻率就好,主要有以下兩個方向:

  • 每隔幾秒發送一次數據 —— 節流
  • 每當用戶停止輸入之後,開始計時,一定時間後發送一次數據 —— 防抖

實現防抖

首先,我們從防抖的方向進行實現:只有當用戶停止輸入一段時間後,纔會將輸入內容輸出在多行文本框中。

window.onload = () => {
    const resEle = document.querySelector("#res");
    function changeOutputVal(value) {
        resEle.value += `\n${ value }`;
    }

    function debounce(fn, delay = 1000) {
        let timer = null;
        return function (...args) {
            console.log(args);
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }

            timer = setTimeout(() => {
                fn.apply(this, args);
            }, delay);
        }
    }

    const outputRes = debounce(changeOutputVal, 1000);

    const inputEle = document.querySelector("#name");

    inputEle.addEventListener("input", (eve) => {
        outputRes(eve.target.value);
    });
}

代碼說明:

  1. 每一次事件被觸發,都會清除當前的 timer 然後重新設置超時調用,即重新計時。 這就會導致每一次高頻事件都會取消前一次的超時調用,導致事件處理程序不能被觸發;
  2. 只有當高頻事件停止,最後一次事件觸發的超時調用才能在delay時間後執行。

運行效果如下:

可以看到,在加入防抖代碼之後,input 事件並不會每次輸入都會輸出在多行文本,而是會在用戶停止輸入 delay 時間之後觸發輸出,頻率確實低了很多。從某種程度上來說,的確優化了頁面顯示效果,給人的視覺感受比較舒服。

總結

巧用防抖函數的,既可以優化性能,又能優化顯示效果,一舉兩得。

~

~

代碼比較粗糙,也比較基礎,後面會逐步向着複雜的方向迭代,望各位看官海涵🙏

~

~

~ 本文完

學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!

大家好!我是〖編程三昧〗的作者 隱逸王,我的公衆號是『編程三昧』,歡迎關注,希望大家多多指教!

知識與技能並重,內力和外功兼修,理論和實踐兩手都要抓、兩手都要硬!

mianshi

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章