1. 程式人生 > >函式節流和函式防抖

函式節流和函式防抖

寫在前面

    在前端開發中,我們知道對於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請求應用中有效提升使用者體驗。