JS之函数防抖和函数节流

函数防抖(debounce)

在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function debounce(func, delay) {
var timeout;
return function(e) {
clearTimeout(timeout);
var context = this, args = arguments
timeout = setTimeout(function(){
func.apply(context, args);
},delay)
};
};

var validate = debounce(function(e) {
console.log("change")
}, 380);

// 绑定监听
document.querySelector("input").addEventListener('input', validate);

应用场景

  • 给按钮加函数防抖防止表单多次提交。

  • 对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数。

  • 判断scroll是否滑到底部,滚动事件+函数防抖

函数节流(throttle)

规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function throttle(fn, threshhold) {
var timeout
var start = new Date;
var threshhold = threshhold || 160
return function () {

var context = this, args = arguments, curr = new Date() - 0

clearTimeout(timeout)//总是干掉事件回调
if(curr - start >= threshhold){
fn.apply(context, args) //只执行一部分方法,这些方法是在某个时间段内执行一次
start = curr
}else{
//让方法在脱离事件后也能执行一次
timeout = setTimeout(function(){
fn.apply(context, args)
}, threshhold);
}
}
}
var mousemove = throttle(function(e) {
console.log(e.pageX, e.pageY)
});

// 绑定监听
document.querySelector("#panel").addEventListener('mousemove', mousemove);

应用场景

函数节流会用在比input, keyup更频繁触发的事件中,如resize, touchmove, mousemove, scroll。throttle 会强制函数以固定的速率执行。因此这个方法比较适合应用于动画相关的场景。

总结

函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。

参考文章