一文教你實現(xiàn)JavaScript防抖優(yōu)化代碼
前言
在我們前端編程中,假如我們要給后端發(fā)送請求,萬一手抖多點了幾次,多發(fā)送了幾遍怎么辦?
解決方案:防抖!這種事就要交給我們專業(yè)的“防抖”先生來處理!
今天,我們就來教大家手搓“防抖”
為什么要防抖
就好比我們想象一個場景:當我們在使用我們的頁面,我們頁面有一個提交數(shù)據(jù)的按鈕!我們每次點擊提交按鈕,都會向我們的后端服務(wù)器發(fā)送一個請求!接下來我們來構(gòu)建一下這樣一個簡單的頁面!
<button id="submit">提交</button>
<script>
let sub = document.getElementById('submit')
sub.addEventListener('click',function(){
console.log('已提交');
})
</script>
這樣,我們就實現(xiàn)了一個提交按鈕!
想象一下!我們每次點擊按鈕都會輸出一個"已提交",代表我們向后端服務(wù)器發(fā)送了一個請求!

這樣我們請求發(fā)送成功了!但是大家發(fā)現(xiàn)沒有?如果我們多次點擊,就會多次輸出“已提交”,也就意味著!我們點了多次,就會向我們的服務(wù)器后端發(fā)送多個請求!!
這會造成什么后果?
- 服務(wù)器壓力增大:假如用戶體量一大!在同一段時間內(nèi)一個人同時發(fā)送多個請求給我們后端,每次點擊都會向服務(wù)器發(fā)送一個請求,如果點擊的頻率過高或者同時點擊的人數(shù)過多,服務(wù)器可能會承受不住壓力,導(dǎo)致響應(yīng)變慢或者服務(wù)崩潰。甚至是“冒煙!!”
- 數(shù)據(jù)重復(fù):不僅如此,如果請求的內(nèi)容不包含唯一標識符(例如,時間戳、隨機數(shù)等),那么后端可能會處理重復(fù)的數(shù)據(jù)。重復(fù)處理數(shù)據(jù),做了多少無用功?
- 資源浪費:而且,過多的請求會消耗更多的網(wǎng)絡(luò)資源,可能會導(dǎo)致網(wǎng)絡(luò)擁堵,影響其他網(wǎng)絡(luò)活動,甚至導(dǎo)致網(wǎng)絡(luò)癱瘓!影響巨大!
- 用戶體驗下降 由于服務(wù)器的負載增大!還會因為卡頓給用戶帶來非常糟糕的體驗!
- 安全性問題:如果每次點擊都會發(fā)送敏感信息(例如,密碼、個人信息等),那么可能會增加這些信息被截獲的風(fēng)險。
所以,為了避免這些情況!我們就要用到今天我們要學(xué)的手段??!防止抖動!!
如何實現(xiàn)抖動?專業(yè)的事要用專業(yè)的方法!
當我們處理一些頻繁觸發(fā)的事件時,比如用戶輸入、滾動等,有時候我們希望在一連串的觸發(fā)中只執(zhí)行一次相應(yīng)的操作,以減輕系統(tǒng)的負擔,提高性能。這時,防抖(Debouncing)就成了我們的得力助手。
防抖的概念很容易理解,就好比你在按電梯的按鈕。你按了一次,電梯并不會立刻啟動,而是等待一段時間,如果在這段時間內(nèi)有人再按了一次,那么等待的時間就會被重置。只有當一段時間內(nèi)沒有新的按壓事件發(fā)生,電梯才會啟動。
在JavaScript中,防抖通常通過設(shè)置一個延遲時間來實現(xiàn)。當事件觸發(fā)時,我們會等待一段時間,如果在這段時間內(nèi)沒有再次觸發(fā)事件,那么我們執(zhí)行相應(yīng)的操作。
我們來給大家上代碼?。≡贋榇蠹壹毤毥庹f!
<button id="btn">提交</button>
<script>
let btn = document.getElementById('btn');
function send() {
console.log('已提交');
}
//addEventListener會把this指向你綁定的對象
btn.addEventListener('click', debounce(send,1000))
function debounce(fn,delay) {
let timer;
let _this = this
return function() {
//arguments
let args = arguments
if(timer)clearTimeout(timer);//clearTimeout(timer);掐滅定時器
timer = setTimeout(()=>{
fn(this,...args)
},delay)
}
}
</script>
這就是我們防止抖動的效果!為大家解釋一下如何實現(xiàn)呢?
- 在
Script中我們用btn獲取id='btn'的元素。 - 接下來我們聲明了一個
send函數(shù),用于發(fā)送請求!console.log('已提交'); - 我們在用
btn添加一個事件監(jiān)聽點擊click事件,當監(jiān)聽到點擊時候之后運行debounce(send,1000)函數(shù),其中接收兩個參數(shù)send為之前聲明的函數(shù),1000為一個時間,傳入定時器為時間1s! - 緊接著,我們又定義一個函數(shù)
debounce(fn,delay)接收兩個參數(shù)! - 在函數(shù)體內(nèi)部,我們又定義了一個變量
timer,用_this指向調(diào)用這個函數(shù)的執(zhí)行上下文對象,但是addEventListener會把this指向你綁定的對象。 - 最后,我們返回了一個函數(shù)體,在在這個函數(shù)體當中,我們用
args接收fn接收的參數(shù),也就是send中接收的參數(shù),我們通過一個if語句,判斷,如果timer存在,就用clearTimeout()掐滅定時器!再讓timer等于一個新的定時器。
這樣意味著!如果,用戶點擊間隔不超過一秒,它可以讓一個函數(shù)在一段時間內(nèi)只執(zhí)行一次,而忽略其他多次調(diào)用。這段代碼中,當用戶點擊按鈕后,send函數(shù)會被延遲執(zhí)行,具體的延遲時間是1000毫秒(1秒)。當用戶連續(xù)點擊按鈕時,send函數(shù)只會在最后一次點擊后1秒內(nèi)執(zhí)行一次。
這樣我們就實現(xiàn)了一個防抖,我們來看看效果!

防抖的好處
- 性能優(yōu)化:在某些場景下,例如用戶在輸入框中輸入文本時,事件處理函數(shù)可能會非常頻繁地觸發(fā)。如果這些事件處理函數(shù)執(zhí)行時間較長,且沒有做防抖處理,那么就可能導(dǎo)致瀏覽器界面卡頓,用戶體驗不佳。而如果使用了防抖處理,事件處理函數(shù)只會在最后一次事件后的一定時間內(nèi)執(zhí)行一次,從而提高了程序的性能。
- 防止多次觸發(fā):在一些需要用戶輸入的情況下,如果用戶連續(xù)觸發(fā)事件(例如連續(xù)點擊按鈕),而事件處理函數(shù)又沒有做防抖處理,就可能會導(dǎo)致一些不希望出現(xiàn)的結(jié)果(例如連續(xù)發(fā)送請求、連續(xù)執(zhí)行某些操作等)。而如果使用了防抖處理,就可以有效地防止這種情況的發(fā)生。
- 減少不必要的操作:在一些需要等待用戶輸入的場景下,如果用戶連續(xù)觸發(fā)事件(例如連續(xù)點擊按鈕),而事件處理函數(shù)又沒有做防抖處理,那么就可能會導(dǎo)致一些不必要的操作被執(zhí)行(例如連續(xù)發(fā)送請求、連續(xù)執(zhí)行某些操作等)。而如果使用了防抖處理,就可以有效地減少這種情況的發(fā)生。
到此這篇關(guān)于一文教你實現(xiàn)JavaScript防抖優(yōu)化代碼的文章就介紹到這了,更多相關(guān)JavaScript防抖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用postMesssage()實現(xiàn)跨域iframe頁面間的信息傳遞方法
下面小編就為大家?guī)硪黄褂胮ostMesssage()實現(xiàn)跨域iframe頁面間的信息傳遞方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家一個參考。一起跟隨小編過來看看吧2016-03-03
js實現(xiàn)翻頁后保持checkbox選中狀態(tài)的實現(xiàn)方法
在項目中有需求如下:上下分頁后,選中的checkbox狀態(tài)保持不變2012-11-11
深入理解Javascript中的valueOf與toString
javascript中所有數(shù)據(jù)類型都擁有valueOf和toString這兩個方法,null除外。它們倆解決javascript值運算與顯示的問題,本文將詳細介紹,有需要的朋友可以參考下2017-01-01
google廣告之另類js調(diào)用實現(xiàn)代碼
這篇文章主要介紹了google廣告之另類js調(diào)用實現(xiàn)代碼,需要的朋友可以參考下2020-08-08

