Javascript函数防抖与节流

为什么要函数防抖和函数节流?

知乎上的回答有很经典的例子:

举个栗子,我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。再举个栗子,假设电梯一次只能载一人的话,10 个人要上楼的话电梯就得走 10 次,是一种浪费资源的行为;而实际生活正显然不是这样的,当电梯里有人准备上楼的时候如果外面又有人按电梯的话,电梯会再次打开直到满载位置,从电梯的角度来说,这时一种节约资源的行为(相对于一次只能载一个人)。 —— 引自大板栗函数节流与函数防抖

浏览器操作中我们经常会遇到短时间内频繁触发的事件,类似于:

  • window的scroll、resize事件等
  • input中change或input事件、keyup、keydown和keypress事件等

这种耗费性能的事情,很可能造成浏览器的卡顿,甚至崩溃。可通过函数防抖和节流来避免这种情况。

函数防抖(Debounce)

debounce: 事件触发停止一定时间后才会执行响应的函数,期间如果重复调用动作,重新计算时间。类似于,按下一个弹簧,只有你松手的时候弹簧才会弹起。本质上是将多次操作合并为一次操作。可用一个定时器维护,事件触发后wait时间内如果事件重复触发,那么取消当前定时器,重新设置一个时延为wait的定时器。

方法定义

/**
*@param fn {function} 事件触发执行的函数
*@param wait {number} 固定时间(事件停止触发多久之后执行函数)
*/
debounce(fn,wait)

方法实现

function debounce(fn,wait){
	var timer;
	return function(){
		var args = Array.prototype.slice.apply(arguments);
		if(timer){
			clearTimeout(timer);
		};
		timer = setTimeout(function(){
			fn.apply(this,args);
		},wait);
	}
}

函数节流(Throttle)

防抖有一个问题,那就是如果事件一直在触发,那么执行函数永远都得不到执行。这种情况下,函数节流此时是较好的方法。它与防抖最大的区别就是,无论事件触发多么频繁,都可以保证在规定时间内可以执行一次执行函数。

throttle:事件触发后执行函数执行期间内事件再次触发,执行函数将不会执行,等规定时间之后事件触发,执行函数方可再次执行。

方法定义

/**
*@param fn {function} 事件触发执行的函数
*@param wait {number} 固定时间(函数执行当前时间与下一次执行时间的最小时间范围)
*/
throttle(fn,wait)

方法实现一

function throttle(fn,wait){
	var isExecute = false;
	return function(){
		var args = Array.prototype.slice.apply(arguments);
		if(isExecute) {
			return;
		}
		isExecute = true;
		setTimeout(function(){
			fn.apply(this,args);
			isExecute = fale
		},wait)
	}
}

方法实现二

function throttle(fn,wait){
	var lastTime = new Date().getTime();
	return function(){
		var args = Array.prototype.slice.apply(arguments);
		var curTime = new Date().getTime();
		if((curTime - lastTime) < wait){return;};
		lastTime = curTime;
		fn.apply(this,args);
	}
}

猜你喜欢

转载自blog.csdn.net/a5161586/article/details/83149859