一文教你實現(xiàn)JavaScript防抖優(yōu)化代碼
前言
在我們前端編程中,假如我們要給后端發(fā)送請求,萬一手抖多點了幾次,多發(fā)送了幾遍怎么辦?
解決方案:防抖!這種事就要交給我們專業(yè)的“防抖”先生來處理!
今天,我們就來教大家手搓“防抖”
為什么要防抖
就好比我們想象一個場景:當我們在使用我們的頁面,我們頁面有一個提交數(shù)據(jù)的按鈕!我們每次點擊提交按鈕,都會向我們的后端服務器發(fā)送一個請求!接下來我們來構(gòu)建一下這樣一個簡單的頁面!
<button id="submit">提交</button> <script> let sub = document.getElementById('submit') sub.addEventListener('click',function(){ console.log('已提交'); }) </script>
這樣,我們就實現(xiàn)了一個提交按鈕!
想象一下!我們每次點擊按鈕都會輸出一個"已提交",代表我們向后端服務器發(fā)送了一個請求!
這樣我們請求發(fā)送成功了!但是大家發(fā)現(xiàn)沒有?如果我們多次點擊,就會多次輸出“已提交”,也就意味著!我們點了多次,就會向我們的服務器后端發(fā)送多個請求!!
這會造成什么后果?
- 服務器壓力增大:假如用戶體量一大!在同一段時間內(nèi)一個人同時發(fā)送多個請求給我們后端,每次點擊都會向服務器發(fā)送一個請求,如果點擊的頻率過高或者同時點擊的人數(shù)過多,服務器可能會承受不住壓力,導致響應變慢或者服務崩潰。甚至是“冒煙!!”
- 數(shù)據(jù)重復:不僅如此,如果請求的內(nèi)容不包含唯一標識符(例如,時間戳、隨機數(shù)等),那么后端可能會處理重復的數(shù)據(jù)。重復處理數(shù)據(jù),做了多少無用功?
- 資源浪費:而且,過多的請求會消耗更多的網(wǎng)絡資源,可能會導致網(wǎng)絡擁堵,影響其他網(wǎng)絡活動,甚至導致網(wǎng)絡癱瘓!影響巨大!
- 用戶體驗下降 由于服務器的負載增大!還會因為卡頓給用戶帶來非常糟糕的體驗!
- 安全性問題:如果每次點擊都會發(fā)送敏感信息(例如,密碼、個人信息等),那么可能會增加這些信息被截獲的風險。
所以,為了避免這些情況!我們就要用到今天我們要學的手段??!防止抖動!!
如何實現(xiàn)抖動?專業(yè)的事要用專業(yè)的方法!
當我們處理一些頻繁觸發(fā)的事件時,比如用戶輸入、滾動等,有時候我們希望在一連串的觸發(fā)中只執(zhí)行一次相應的操作,以減輕系統(tǒng)的負擔,提高性能。這時,防抖(Debouncing)就成了我們的得力助手。
防抖的概念很容易理解,就好比你在按電梯的按鈕。你按了一次,電梯并不會立刻啟動,而是等待一段時間,如果在這段時間內(nèi)有人再按了一次,那么等待的時間就會被重置。只有當一段時間內(nèi)沒有新的按壓事件發(fā)生,電梯才會啟動。
在JavaScript中,防抖通常通過設置一個延遲時間來實現(xiàn)。當事件觸發(fā)時,我們會等待一段時間,如果在這段時間內(nèi)沒有再次觸發(fā)事件,那么我們執(zhí)行相應的操作。
我們來給大家上代碼??!再為大家細細解說!
<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í)行時間較長,且沒有做防抖處理,那么就可能導致瀏覽器界面卡頓,用戶體驗不佳。而如果使用了防抖處理,事件處理函數(shù)只會在最后一次事件后的一定時間內(nèi)執(zhí)行一次,從而提高了程序的性能。
- 防止多次觸發(fā):在一些需要用戶輸入的情況下,如果用戶連續(xù)觸發(fā)事件(例如連續(xù)點擊按鈕),而事件處理函數(shù)又沒有做防抖處理,就可能會導致一些不希望出現(xiàn)的結(jié)果(例如連續(xù)發(fā)送請求、連續(xù)執(zhí)行某些操作等)。而如果使用了防抖處理,就可以有效地防止這種情況的發(fā)生。
- 減少不必要的操作:在一些需要等待用戶輸入的場景下,如果用戶連續(xù)觸發(fā)事件(例如連續(xù)點擊按鈕),而事件處理函數(shù)又沒有做防抖處理,那么就可能會導致一些不必要的操作被執(zhí)行(例如連續(xù)發(fā)送請求、連續(xù)執(zhí)行某些操作等)。而如果使用了防抖處理,就可以有效地減少這種情況的發(fā)生。
到此這篇關(guān)于一文教你實現(xiàn)JavaScript防抖優(yōu)化代碼的文章就介紹到這了,更多相關(guān)JavaScript防抖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript ready和load事件的區(qū)別示例介紹
ready是在DOM加載完成就觸發(fā);load是在加載完所有頁面內(nèi)容才會觸發(fā),下為大家簡要介紹下,不知道的朋友可以參考下2013-08-08javascript判斷機器是否聯(lián)網(wǎng)的2種方法
只有機器已經(jīng)聯(lián)網(wǎng)以后,web應用才能啟動,下面使用javascript判斷機器是否聯(lián)網(wǎng),具體判斷代碼如下,有此需求的朋友可以參考下2013-08-08