在一些常見的觸發resize事件和scroll的情況下,我們會使用函數防抖,來控制函數的觸發次數,因為resize實時在變化,那函數就要實時在觸發,這會帶來一個致命的問題,對一些機型老舊的電腦,有可能使瀏覽器卡頓,下面我們來看一個例子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js之函數節流防抖</title> <style> * {padding: 0; margin: 0;} .box {width: 800px;height: 1200px;} </style> </head> <body> <div class="container"> <div class="box" style="background: black"></div> <div class="box" style="background: blue"></div> </body> <script> window.onload = function() { let num = 0 function scrollTap() { num++ console.log('num為 ${num}') } document.addEventListener('scroll', scrollTap) } </script> </html>
此時我們可以看到每次scroll事件觸發時,num的值會發生變化,這會加重cpu的負擔,造成性能問題,但是當我們使用防抖函數時,我們就可以避免實時調用函數的情況,他只會在最后一次scroll事件觸發后調用,函數防抖其實是先初始化了一個定時器,每次事件在延遲事件類被觸發時都會重置定時器,直至最后一個事件觸發完。
var decounce = function(fn, delay) { let timer = null return function() { let _this = this clearTimeout(timer) // 每次調用debounce函數都會將前一次的timer清空,確保只執行一次 timer = setTimeout(() => { fn.apply(_this,args) }, delay) } }
document.addEventListener('scroll', decounce(scrollTap, 1000)); // 調用decounce函數
此時我們的函數觸發就變少了。
當然,函數節流與之想類似,就是在指定的時間段內只執行一次期望函數,在我們的聯想搜索時,常常會出現當前字符觸發的聯想字詞還沒來得及出現就已經觸發下一個聯想字詞了,這里我們也需要用到防抖。