函数防抖和节流
防抖
对于触发非常频繁又没有必要每次都执行的事件,希望合并到一次去执行;
实现思路:
事件触发后,在规定的时间范围内如果事件重复触发,那么忽略之前触发的事件,并且重新开始计时,直到某一次事件触发后大于规定时间,我们才执行需要执行的代码段(函数);
看起来就像是只执行了用户快速操作的最后一次事件;
- 代码实现:
var debounce = function(fn, delayTime) {
var timeId;
return function() {
var context = this, args = arguments;
timeId && clearTimeout(timeout);
timeId = setTimeout(function{
fn.apply(context, args);
}, delayTime)
}
}
- 简单分析:
利用闭包保存一个setTimeout的id,如果在delayTime内闭包中的函数再次执行,会立刻clear掉上一次的延时回调,生成一个新的延时回调;如果超过delayTime没有再次执行闭包中的函数,那延时回调就会被执行,这样才算是真正执行了需要执行的事件。
- 应用场景:
- 给按钮加函数防抖防止表单多次提交。
- 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。
- 判断scroll是否滑到底部,滚动事件+函数防抖
节流
对于触发非常频繁的事件,在规定时间间隔后才能执行,在规定时间间隔内触发的事件会被忽略,但是不会重新开始计时;
- 实现思路:
规定一个时间,一次触发后,在规定时间内触发的事件都忽略,超过规定时间后可以重新执行触发的事件;
- 代码实现:(两种)
- 时间戳
var throttle = (fn, delayTime) => {
var _start = Date.now();
return function() {
var _now = Date.now(), context = this, args = arguments;
if(_now - _start >= delayTime) {
fn.apply(context, args);
_start = Date.now();
}
}
}
- 简单分析:
先设定一个初始时间,然后每次执行闭包内的函数都与当前时间做比较,如果小于delayTime,什么也不做,忽略该次事件,如果大于delayTime,执行回调函数fn,重置初始时间;
- 定时器
var throttle = function(fn, delayTime) {
var flag;
return function() {
var context = this, args = arguments;
if(!flag) {
fn.apply(context, args);
flag = setTimeout(function() {
flag = false;
}, delayTime);
}
}
}
- 简单分析:
通过设定一个标志位,通过标志位判断是否可以执行回调函数,在延时函数中执行回调的同时将标志位置为可再次执行,这样就保证了在规定时间之后能再次执行需要的回调函数;
- 应用场景:
- 游戏中的刷新率
- DOM元素拖拽
- Canvas画笔功能
防抖和节流区别
- 防抖是把之前频繁的事件触发都放到某一次停顿时触发,可以理解为执行最后一次(并不准确);节流则是执行完一次以后等待一段时间之后才能再次执行,可以理解为第一次;这意味着防抖执行的是最新的,而节流在等待中如果事件有更新是不会执行的,会被忽略,这两者应用场景不同;
- 防抖适合多次事件一次响应的情况;
- 节流适合大量事件按时间做平均分配触发。
参考:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。