如何理解JS事件的防抖與節(jié)流?
本文轉(zhuǎn)載自微信公眾號「新鈦云服」,作者方章和。轉(zhuǎn)載本文請聯(lián)系新鈦云服公眾號。
在平時的編碼過程中,當(dāng)紿瀏覽器注冊一個時間,經(jīng)常會遇到一些執(zhí)行次數(shù)非常頻繁的事件,如scroll,resize等,事件頻繁的執(zhí)行會導(dǎo)致瀏覽器進行大量的計算而引發(fā)頁面卡頓假死的情況,為些我們需要通過一些手段來解決這個問題,所以就有了防抖和節(jié)流這兩個技術(shù)。
事件節(jié)流 throttle
是指在某段時間內(nèi),不管你觸發(fā)了多少次回調(diào)事件,我都只認第一次,并在計時結(jié)束時給予響應(yīng),至于后面你再觸發(fā)多少次回調(diào)我都不會予以回應(yīng)。代碼實現(xiàn)如下:
- // fn執(zhí)行的函數(shù), interval是時間間隔的閾值, 意為多久后執(zhí)行,單位毫秒
- function throttle(fn, interval) {
- // 上一次觸發(fā)回調(diào)的時間
- let last = 0
- return function () {
- let context = this
- let args = arguments
- let now = +new Date()
- // 判斷上次觸發(fā)的時間和本次觸發(fā)的時間差是否小于設(shè)置的間隔時間
- if (now - last >= interval) {
- // 如果時間間隔大于我們設(shè)定的時間間隔閾值,則執(zhí)行回調(diào)
- last = now;
- fn.apply(context, args);
- }
- }
- }
- // 紿scroll事件增加節(jié)流
- const newScroll = throttle(() => console.log('滾動了'), 1000)
- document.addEventListener('scroll', newScroll)
事件防抖Debounce
與事件節(jié)流怡好相反,事件防抖只認最后一次,不管你前面觸發(fā)了多少次我都不管,我只執(zhí)行你最后一次觸發(fā)事件的回調(diào),代碼實現(xiàn)如下:
- // fn執(zhí)行的函數(shù), delay是延遲多久執(zhí)行的時間, 意為多久后才觸發(fā)事件,單位毫秒
- function debounce(fn, delay) {
- let timer = null
- return function () {
- let context = this
- let args = arguments
- // 每次事件被觸發(fā)時,都去清除之前的舊定時器
- if(timer) {
- clearTimeout(timer)
- }
- timer = setTimeout(function () {
- fn.apply(context, args)
- }, delay)
- }
- }
- const newScroll = debounce(() => console.log('滾動了'), 1000)
- document.addEventListener('scroll', newScroll)
函數(shù)防抖的應(yīng)用場景
連續(xù)的事件,只需觸發(fā)一次回調(diào)的場景有:
搜索框搜索輸入。只需用戶最后一次輸入完,再發(fā)送請求
手機號、郵箱驗證輸入檢測
窗口大小Resize。只需窗口調(diào)整完成后,計算窗口大小。防止重復(fù)渲染。
函數(shù)節(jié)流的應(yīng)用場景
間隔一段時間執(zhí)行一次回調(diào)的場景有:
- 滾動加載,加載更多或滾到底部監(jiān)聽
- 百度搜索框,搜索聯(lián)想功能
- 高頻點擊提交,表單重復(fù)提交

































