1、防抖
事件触发n秒后再执行回调,如果在n秒内再次触发的话,就要重新计算时间。就是说事件什么时候不触发了,就在那个点的n秒后执行回调。
比如说:用户在文本框输入数据,不停的输入这个时候不停的获取数据那也是不科学的呀,可以等上个100毫秒之后再去获取文本框的内容
体会:我以前一直很不理解到底防抖很节流有啥区别没有,感觉不都是要求n秒后触发吗?但其实是有很大的区别。
function debounce(fn, delay = 1000) {
let time = null;
return function () {
// 获取当前this,保存下来
let that = this;
let args = arguments;
console.log(time)//打印输出触发的定时器
if (time) clearTimeout(time);
time = setTimeout(() => {
console.log("防抖")
fn.call(that, ...args);
}, delay)
}
}
let input = document.querySelector('input')
input.addEventListener('input', debounce(b, 1000))
function b(x) {
//这里的this表示的是当前作用域
// console.log(this);
// console.log(x);
}
当我们在input框中一直输入内容的时候,同时会一直创建定时器。但是再次触发回调函数的时候,又会把上次的定时器清除。一直到用户不再触发回调函数为止,这个时候定时器time为空,再次创建定时器,会过了n秒后执行定时器里面的内容。如下图所示:
可以看出,无论是触发多少次,都是在不再触发之后,过了n秒之后定时器才执行的。
2、节流
n秒内只运行一次,若在n秒内重复触发,只有一次生效。
版本①:以定时器的方式去完成节流
function throttle(fn, delay = 1000) {
let time = null;
return function () {
let that = this;
let args = arguments;
// 如果已经存在定时器了,就不做处理
console.log(time)
if (!time) {
time = setTimeout(() => {
console.log("节流")
fn.call(that, ...args);
time = null
}, delay)
}
}
}
let input = document.querySelector('input');
input.addEventListener('input', throttle(fn, 1000));
function fn() {
console.log(arguments);
}
节流跟防抖不一样,我们从代码里面可以看出,它是上来就创建了定时器,n秒内再触发的时候,会判断定时器是否为空。n秒后定时器执行,time置为空。n秒后再次触发,步骤跟上面是一样的。
其中null表示的是定时器创建之前,1表示,在n秒内连续触发了,n秒一到就会执行节流。
3、应用场景
防抖是在连续的事件内,只需触发一次回调的场景:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
- 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流在每隔一段时间内执行一次回调函数的场景:
- 滚动加载,加载更多或滚动到底部监听
- 搜索框,搜索联想功能