函数防抖(debounce)
防抖动是将多次执行变为最后一次执行。
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
打开控制台查看:
没有防抖的输入:
有防抖的输入:
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
27
28
29
30
31
32
/**
*
* @param fun {Function} 实际要执行的函数
* @param delay {Number} 延迟时间,单位是毫秒(ms)
*
* @return {Function} 返回一个“防反跳”了的函数
*/
function ajax(content) {
console.log('刚刚输入的内容:' + content)
}
//无防抖
let inputA = document.getElementById('unDebounce')
inputA.addEventListener('keyup', function (e) {
ajax(e.target.value)
})
// 防抖
function debounce(fun, delay) {
// args 就是 e.target.value
return function (args) {
let that = this;
// 清除上一次防抖的计时器
clearTimeout(fun.id);
fun.id = setTimeout(function () {
fun.call(that, args);
}, delay);
}
}
let inputB = document.getElementById('debounce');
let debounceAjax = debounce(ajax, 500);
inputB.addEventListener('keyup', function (e) {
debounceAjax(e.target.value);
})
可用箭头函数简化代码:
1
2
3
4
5
6
7
8
9
10
11
// 防抖
function debounce(fun, delay) {
// args 就是 e.target.value
return function (args) {
// 清除上一次防抖的计时器
clearTimeout(fun.id);
fun.id = setTimeout(() => {
fun(args);
}, delay);
}
}
可见在加入了防抖以后,当你在频繁的输入时,并不会发送请求,只有当你在指定间隔内没有输入时,才会执行函数。像是LOL中的回城技能,只有等待蓝条满了才会真正触发回城。
函数节流(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
27
28
29
30
31
32
33
34
35
36
37
38
/**
*
* @param fun {Function} 实际要执行的函数
* @param delay {Number} 执行间隔,单位是毫秒(ms)
*
* @return {Function} 返回一个“节流”函数
*/
function throttle(fun, delay) {
// 记录上次执行的时间
let last;
// 定时器
let deferTimer;
// 返回的函数,每过 delay 毫秒就执行一次 fn 函数
return function() {
// 保存函数调用时的上下文和参数,传递给 fn
let that = this;
let _args = arguments;
let now = +new Date();
// 如果距离上次执行 fn 函数的时间小于 delay,那么就放弃执行 fn,并重新计时
if (last && now < last + delay) {
clearTimeout(deferTimer);
// 保证在当前时间区间结束后,再执行一次 fn
deferTimer = setTimeout(function() {
last = now;
fun.apply(that, _args);
}, delay);
} else {
// 在时间区间的最开始和到达指定间隔的时候执行一次 fn
last = now;
fun.apply(that, _args);
}
};
}
let throttleAjax = throttle(ajax, 1000);
let inputC = document.getElementById("throttle");
inputC.addEventListener("keyup", function(e) {
throttleAjax(e.target.value);
});