在前端開發的過程中,我們經常會需要繫結一些持續觸發的事件,如 resize、scroll、mousemove 等等,但有些時候我們並不希望在事件持續觸發的過程中那麼頻繁地去執行函式。
通常這種情況下我們怎麼去解決的呢?一般來講,防抖和節流是比較好的解決方案。
讓我們先來看看在事件持續觸發的過程中頻繁執行函式是怎樣的一種情況。
html 檔案中**如下
<div
id="content"
style
="height:150px;line-height:150px;text-align:center; color: #fff;background-color:#ccc;font-size:80px;"
>
div>
<
script
>
let num =1
; let content
=document.getelementbyid(
'content');
function
count() ;
content.onmousemove
=count;
script
>
在上述**中,div 元素繫結了 mousemove 事件,當滑鼠在 div(灰色)區域中移動的時候會持續地去觸發該事件導致頻繁執行函式。
在沒有通過其它操作的情況下,函式被頻繁地執行導致頁面上資料變化特別快。所以,接下來讓我們來看看防抖和節流是如何去解決這個問題的。
防抖(debounce)
所謂防抖,就是指觸發事件後在 n 秒內函式只能執行一次,如果在 n 秒內又觸發了事件,則會重新計算函式執行時間。
防抖函式分為非立即執行版和立即執行版。
非立即執行版:
function debounce(func, wait) , wait);}}
非立即執行版的意思是觸發事件後函式不會立即執行,而是在 n 秒後執行,如果在 n 秒內又觸發了事件,則會重新計算函式執行時間。
我們依舊使用上述繫結 mousemove 事件的例子,通過上面的防抖函式,我們可以這麼使用
content.onmousemove = debounce(count,1000);
觸發事件後函式 1 秒後才執行,而如果我在觸發事件後的 1 秒內又觸發了事件,則會重新計算函式執行時間。
上述防抖函式的**還需要注意的是 this 和 引數的傳遞
let context = this;let args = arguments;
防抖函式的**使用這兩行**來獲取 this 和 引數,是為了讓 debounce 函式最終返回的函式 this 指向不變以及依舊能接受到 e 引數。
立即執行版
function debounce(func,wait) , wait)}}
立即執行版的意思是觸發事件後函式會立即執行,然後 n 秒內不觸發事件才能繼續執行函式的效果。
在開發過程中,我們需要根據不同的場景來決定我們需要使用哪乙個版本的防抖函式,一般來講上述的防抖函式都能滿足大部分的場景需求。但我們也可以將非立即執行版和立即執行版的防抖函式結合起來,實現最終的雙劍合璧版的防抖函式。
/*** @desc 函式防抖
* @param func 函式
* @param wait 延遲執行毫秒數
* @param immediate true 表立即執行,false 表非立即執行
*/function debounce(func,wait,immediate) , wait)
}else , wait);}}
}
節流(throttle)
所謂節流,就是指連續觸發事件但是在 n 秒中只執行一次函式。節流會稀釋函式的執行頻率。
對於節流,一般有兩種方式可以實現,分別是時間戳版和定時器版。
時間戳版:
function throttle(func, wait)}}
使用方式如下
content.onmousemove = throttle(count,1000);
在持續觸發事件的過程中,函式會立即執行,並且每 1s 執行一次。
定時器版:
function throttle(func, wait) , wait)}}}
使用方式同上
在持續觸發事件的過程中,函式不會立即執行,並且每 1s 執行一次,在停止觸發事件後,函式還會再執行一次。
我們應該可以很容易的發現,其實時間戳版和定時器版的節流函式的區別就是,時間戳版的函式觸發是在時間段內開始的時候,而定時器版的函式觸發是在時間段內結束的時候。
同樣地,我們也可以將時間戳版和定時器版的節流函式結合起來,實現雙劍合璧版的節流函式。
雙劍合璧版:
/*** @desc 函式節流
* @param func 函式
* @param wait 延遲執行毫秒數
* @param type 1 表時間戳版,2 表定時器版
*/function throttle(func, wait ,type) else if(type===2)
return function()
}else if(type===2), wait)}}
}}
防抖和節流 什麼是防抖和節流
目錄二 節流 有這樣一種情況,想象有乙個表單,點選提交按鈕就傳送請求給伺服器。如果使用者在很短的時間間隔內 手抖 點選了多次,又或者是惡意點選,那麼就將傳送多個請求。該行為將造成伺服器額外的不必要負載。所謂防抖,實際上就是是處理這種常見的情況的描述。submit該段 當點選submit按鈕的時候,將...
防抖和節流
在前端開發過程中,我們經常需要繫結一些持續觸發事件,如 resize scroll mousemove等等,但有些時候我們並不希望在事件持續觸發的過程中那麼頻繁的去執行函式。通常這種情況下,我們怎麼去解決呢?一般來講,防抖和節流是比較好的解決方案。一 函式的防抖 1 什麼是函式防抖 函式防抖 deb...
防抖和節流
防抖和節流的作用都是防止函式多次呼叫。區別在於,假設乙個使用者一直觸發這個函式,且每次觸發函式的間隔小於設定的時間,防抖的情況下只會呼叫一次,而節流的情況會每隔一定時間呼叫一次函式。1.防抖 函式防抖 debounce n秒內函式只會執行一次,如果n秒內高頻事件再次被觸發,則重新計算時間。如下例,對...