在前端開發的過程中,我們經常會需要繫結一些持續觸發的事件,如 resize、scroll、mousemove 等等,但有些時候我們並不希望在事件持續觸發的過程中那麼頻繁地去執行函式。
通常這種情況下我們怎麼去解決的呢?一般來講,防抖和節流是比較好的解決方案。
讓我們先來看看在事件持續觸發的過程中頻繁執行函式是怎樣的一種情況。
html 檔案中**如下
let num = 1;
let content = document.getelementbyid('content');
function count() , 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) , wait)
使用方式同上,效果如下
可以看到,在持續觸發事件的過程中,函式不會立即執行,並且每 1s 執行一次,在停止觸發事件後,函式還會再執行一次。
我們應該可以很容易的發現,其實時間戳版和定時器版的節流函式的區別就是,時間戳版的函式觸發是在時間段內開始的時候,而定時器版的函式觸發是在時間段內結束的時候。
同樣地,我們也可以將時間戳版和定時器版的節流函式結合起來,實現雙劍合璧版的節流函式。
雙劍合璧版:
* @desc 函式節流
* @param func 函式
* @param wait 延遲執行毫秒數
* @param type 1 表時間戳版,2 表定時器版
function throttle(func, wait ,type) else if(type===2)else if(type===2), wait)
防抖和節流 什麼是防抖和節流
目錄二 節流 有這樣一種情況,想象有乙個表單,點選提交按鈕就傳送請求給伺服器。如果使用者在很短的時間間隔內 手抖 點選了多次,又或者是惡意點選,那麼就將傳送多個請求。該行為將造成伺服器額外的不必要負載。所謂防抖,實際上就是是處理這種常見的情況的描述。submit該段 當點選submit按鈕的時候,將...
函式防抖與節流
因為在寫前端頁面時需要監控滑鼠滾輪,這導致在很短時間內,會觸發很多次函式,造成頁面卡頓堵塞,正巧自己在看github時看到了這個,所以自己記錄一下。函式防抖就是讓某個函式在上一次執行後,滿足等待某個時間內不再觸發此函式後再執行,而在這個等待時間內再次觸發此函式,等待時間會重新計算。underscor...
函式防抖與節流
在前端開發的過程中,我們經常會需要繫結一些持續觸發的事件,如 resize scroll mousemove 等等,但在事件持續觸發期間頻繁的執行函式在很大程度上造成了不必要的浪費。通常這種情況下我們一般使用防抖和節流是這兩種解決方案。讓我們先來看看在事件持續觸發的過程中頻繁執行函式是怎樣的一種情況...