有一些瀏覽器事件可以在很短的時間內快速啟動多次,例如調整窗口大小或向下滾動頁面。例如,如果將事件偵聽器綁定到窗口滾動事件上,並且用戶繼續非常快速地向下滾動頁面,你的事件可能會在3秒的范圍內被觸發數千次。這可能會導致一些嚴重的性能問題。
函數防抖動(Debouncing) 是解決這個問題的一種方式,通過限制需要經過的時間,直到再次調用函數。一個正確實現函數防抖的方法是:把多個函數放在一個函數里調用,隔一定時間執行一次。
// debounce函數用來包裹我們的事件 function debounce(fn, delay) { // 持久化一個定時器 timer let timer = null; // 閉包函數可以訪問 timer return function() { // 通過 'this' 和 'arguments' // 獲得函數的作用域和參數 let context = this; let args = arguments; // 如果事件被觸發,清除 timer 並重新開始計時 clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, delay); } } // 當用戶滾動時函數會被調用 function foo() { console.log('You are scrolling!'); } // 在事件觸發的兩秒后,我們包裹在debounce中的函數才會被觸發 let elem = document.getElementById('container'); elem.addEventListener('scroll', debounce(foo, 2000));