函式節流和函式防抖
阿新 • • 發佈:2019-02-17
寫在前面
在前端開發中,我們知道對於DOM的頻繁操作是非常消耗資源的,尤其是對於瀏覽器的onresize,onscroll事件進行響應去操作DOM元素的時候,有時候會看到瀏覽器卡頓,使用者體驗非常不好。但是我們又要監聽瀏覽器的onresize,onscroll事件,這時候函式節流(throttle)和函式防抖(debounce)就發揮作用了。
函式節流原理
對於連續觸發的事件,我們通過設定一個定時器,讓其在過了特定時間t1後觸發,如果在t1時間內再次觸發了該事件,則清除上一次計時器,重新計時,等待新計時時間的到來。
函式節流的實現
下面一個例子,通過函式節流實現document.body的縮放,在縮放過程中不會觸發自定義的函式,只有當停止縮放的時候才會執行函式:
var throttle = { timeId:null, zoomBody: function(){ //邏輯程式碼... console.log(99999); }, zoomHandle: function(timeInternal){ clearTimeout(this.timeId); this.timeId = setTimeout(this.zoomBody); } } document.body.onresize = function(){ throttle.zoomHandle(500); }
以上程式碼只有在停止縮放時才會觸發自定義的throttle.zoomBody函式。有時候這種方式並不能滿足需求,比如使用者在拖拽瀏覽器視窗時,去動態響應某個控制元件的寬度/高度,而不是等到停止拖動時才去自適應視窗。此時我們可以使用函式防抖的功能。
函式防抖原理
函式防抖是在函式節流的基礎上,每隔固定的時間,不管定時器觸發沒觸發,都會執行一遍自定義函式。
函式防抖的實現
var throttle = { timeId:null, startTime: new Date(), zoomBody: function(){ //邏輯程式碼... console.log(99999); }, zoomHandle: function(timeInternal,maxInternal){ clearTimeout(this.timeId); var cur = new Date(); if(cur - this.startTime > maxInternal){ this.zoomBody(); this.startTime = cur; }else{ this.timeId = setTimeout(this.zoomBody,timeInternal); } } } document.body.onresize = function(){ throttle.zoomHandle(500,2000); }
以上程式碼,在縮放過程中,每隔2秒執行一次throttle.zoomBody函式,避免了等待停止縮放才執行的弊端。
總結
函式防抖的合理應用能夠幫助我們充分節省cpu,記憶體等資源,同時又通過一定的時延間隔去執行自定義函式,在一些頻繁的DOM操作,http請求應用中有效提升使用者體驗。