在前端開發中會遇到一些頻繁的事件觸發,比如:
window 的 resize、scroll
mousedown、mousemove
keyup、keydown
……為此,我們舉個示例**來了解事件如何頻繁的觸發:
我們寫個index.html
檔案:
debouncetitle>#container
style>
head>
div>
script>
body>
html>
debounce.js
檔案的**如下:
var count = 1;我們來看看效果:var container = document.getelementbyid('container');
function getuseraction() ;
container.onmousemove = getuseraction;
從左邊滑到右邊就觸發了 165 次 getuseraction 函式!
因為這個例子很簡單,所以瀏覽器完全反應的過來,可是如果是複雜的**函式或是 ajax 請求呢?假設 1 秒觸發了 60 次,每個**就必須在 1000 / 60 = 16.67ms 內完成,否則就會有卡頓出現。
為了解決這個問題,一般有兩種解決方案:
debounce 防抖
throttle 節流
今天重點講講防抖的實現。
防抖的原理就是:你儘管觸發事件,但是我一定在事件觸發 n 秒後才執行,如果你在乙個事件觸發的 n 秒內又觸發了這個事件,那我就以新的事件的時間為準,n 秒後才執行,總之,就是要等你觸發完事件 n 秒內不再觸發事件,我才執行,真是任性吶!
根據這段表述,我們可以寫第一版的**:
// 第一版如果我們要使用它,以最一開始的例子為例:function debounce(func, wait)
}
container.onmousemove = debounce(getuseraction, 1000);現在隨你怎麼移動,反正你移動完 1000ms 內不再觸發,我才執行事件。看看使用效果:
頓時就從 165 次降低成了 1 次!
棒棒噠,我們接著完善它。
如果我們在getuseraction
函式中console.log(this)
,在不使用debounce
函式的時候,this
的值為:
div>但是如果使用我們的 debounce 函式,this 就會指向 window 物件!
所以我們需要將 this 指向正確的物件。
我們修改下**:
// 第二版現在 this 已經可以正確指向了。讓我們看下個問題:function debounce(func, wait) , wait);
}}
j**ascript 在事件處理函式中會提供事件物件 event,我們修改下 getuseraction 函式:
function getuseraction(e) ;如果我們不使用 debouce 函式,這裡會列印 mouseevent 物件,如圖所示:
但是在我們實現的 debounce 函式中,卻只會列印 undefined!
所以我們再修改一下**:
// 第三版到此為止,我們修復了兩個小問題:function debounce(func, wait) , wait);
}}
this 指向
event 物件
這個時候,**已經很是完善了,但是為了讓這個函式更加完善,我們接下來思考乙個新的需求。
這個需求就是:
我不希望非要等到事件停止觸發後才執行,我希望立刻執行函式,然後等到停止觸發 n 秒後,才可以重新觸發執行。
想想這個需求也是很有道理的嘛,那我們加個 immediate 引數判斷是否是立刻執行。
// 第四版再來看看使用效果:function debounce(func, wait, immediate) , wait)
}else , wait);}}
}
// 第五版最後我們再思考乙個小需求,我希望能取消 debounce 函式,比如說我 debounce 的時間間隔是 10 秒鐘,immediate 為 true,這樣的話,我只有等 10 秒後才能重新觸發事件,現在我希望有乙個按鈕,點選後,取消防抖,這樣我再去觸發,就可以又立刻執行啦,是不是很開心?function debounce(func, wait, immediate) , wait)
}else , wait);
}return result;
}}
為了這個需求,我們寫最後一版的**:
// 第六版那麼該如何使用這個 cancel 函式呢?依然是以上面的 demo 為例:function debounce(func, wait, immediate) , wait)
}else , wait);
}return result;
};debounced.cancel = function() ;
return debounced;
}
var count = 1;演示效果如下:var container = document.getelementbyid('container');
function getuseraction(e) ;
var setuseaction = debounce(getuseraction, 10000, true);
container.onmousemove = setuseaction;
document.getelementbyid("button").addeventlistener('click', function())
至此我們已經完整實現了乙個 underscore 中的 debounce 函式,恭喜,撒花!
相關的**可以在 github 部落格倉庫 中找到
input防抖節流之防抖vue例項
節流的應用場景頻繁會在input實時搜尋展示相應內容,所以為了避免無線向後端傳送請求以下是核心 對這個input進行節流看下圖 你只需要將this.refreshall 換成自己要執行的邏輯即可 對於獲取監聽input的值得話在可以有兩種比較合適的方式 1.通過input上新增input事件進行監聽...
跟著寵物學健身
貓有著無比柔軟和輕巧的身段,狗則充滿活力 動作靈活,它們的一些行為動作均可讓我們模仿,這麼做對健身大有好處 學貓狗走路。學 狗步 像狗那樣,四肢落地。用右手和左腳 左手和右 替伸出,移動身體前行。每天堅持走20步。可緩解長久站立或行走引起的腰痛 胃下垂 痔瘡及下肢腫脹等,對防治腰痛尤其有效。邁 貓步...
函式防抖和節流(一) 防抖函式
一.什麼是函式防抖?1 概念 函式防抖 debounce 就是指觸發事件後,在延遲時間內函式只能執行一次,如果觸發事件後在延遲時間內又觸發了事件,則會重新計算函式延執行時間。等延遲時間計時完畢,則執行目標 2 例如 坐電梯的時候,如果電梯檢測到有人進來 觸發事件 就會多等待 10 秒,此時如果又有人...