记录一次简单的防抖节流
前端小菜-贺俊兰 2020-08-28 JavaScript
# 防抖
# 定义
防抖的原理是不管你在一段时间内如何不停的触发事件,只要设置了防抖,则只在触发n秒后才执行。如果我们在一个事件触发的n秒内又触发了相同的事件,那我们便以新的事件为标准,n秒之后再执行。
个人理解:函数防抖就是法师放技能的时候要读条,技能读条没完再按技能就会重新读条。
# 使用场景
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
- 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
# 简单的代码实现
原理:将若干个函数调用合成为一次,并在给定时间过去之后仅被调用一次。
function debounce(fn, delay) {
// 维护一个 timer,用来记录当前执行函数状态
let timer = null;
return function() {
// 通过 ‘this’ 和 ‘arguments’ 获取函数的作用域和变量
let context = this;
let args = arguments;
// 清理掉正在执行的函数,并重新执行
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(context, args);
}, delay);
}
}
let flag = 0; // 记录当前函数调用次数
// 当用户滚动时被调用的函数
function foo() {
flag++;
console.log('函数调用次数:', flag);
}
// 在 debounce 中包装我们的函数,过 2 秒触发一次
document.body.addEventListener('scroll', debounce(foo, 2000));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 节流
# 定义
在指定间隔内任务只执行1次。规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
个人理解:类似限时发放福利,每个人在规定时间内只能领取一次。
# 使用场景
- 滚动加载,加载更多或滚到底部监听
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 高频点击提交,表单重复提交
# 简单的代码实现
原理:节流函数不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数。 代码实现有两种,一种是时间戳,另一种是定时器
时间戳实现:
function throttle(func, delay){
let prev = Date.now();
return function(){
const context = this;
const args = arguments;
const now = Date.now();
if(now - prev >= delay){
func.apply(context, args);
prev = Date.now();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
当高频事件触发时,第一次应该会立即执行(给事件绑定函数与真正触发事件的间隔如果大于delay的话),而后再怎么频繁触发事件,也都是会每delay秒才执行一次。而当最后一次事件触发完毕后,事件也不会再被执行了。
定时器实现:当触发事件的时候,我们设置一个定时器,在触发事件的时候,如果定时器存在,就不执行;直到delay秒后,定时器执行执行函数,清空定时器,这样就可以设置下个定时器。
fucntion throttle(func, delay){
let timer = null;
return funtion(){
let context = this;
let args = arguments;
if(!timer){
timer = setTimeout(function(){
func.apply(context, args);
timer = null;
}, delay);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
当第一次触发事件时,肯定不会立即执行函数,而是在delay秒后才执行。 之后连续不断触发事件,也会每delay秒执行一次。 当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。
# 总结
- 函数防抖和函数节流都是防止某一时间段内频繁触发,但是这两兄弟之间的原理却不一样。
- 函数防抖是某一段时间内只执行一次,多次触发时间重新计算,而函数节流是间隔时间执行。