1.定义
函数防抖(debounce)
函数防抖,就是指触发事件后,在 n 秒后只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数的执行时间。
简单的说,当一个动作连续触发,只执行最后一次。
函数节流(throttle)
限制一个函数在一定时间内只能执行一次
为了方便理解,我们首先通过一个可视化的工具,感受一下三种环境(正常情况、函数防抖情况 debounce、函数节流 throttle)下,对于mousemove事件回调的执行情况。
竖线的疏密代表事件执行的频繁程度。可以看到,正常情况下,竖线非常密集,函数执行很频繁。而 debounce (函数防抖)则很稀疏,只有当鼠标停止移动时,才会执行一次。throttle(函数节流)分布的较为均匀,每过一段时间就会执行一次。
2.简单实现
function debounce(fn, delay = 500) {
// timer 是在闭包中的
let timer = null;
return function() {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
}, delay)
}
}
// test debounce 返回一个函数
input1 = document.getElementById('input1')
input1.addEventListener('keyup', debounce(function () {
console.log(input1.value)
}, 600))
function throttle(fn, delay) {
let timer = null
return function() {
if (timer) {
return
}
timer = setTimeout(() => {
fn.apply(this, arguments)
timer = null
})
}
}
// test
let div1 = document.getElementById('div1')
div1.addEventListener('drag', throttle(function(e) {
console.log(e.offsetX, e.offsetY)
}, 100))
3. 应用
函数防抖(debounce)的应用场景
连续的事件,只需触发一次的回调场景有:
- 搜索框搜索输入。只需要用户最后一次输入完再发送请求
- 手机号、邮箱格式的输入验证检测
- 高频点击提交,表单重复提交。
函数节流(throttle)的应用场景
间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚动到底部监听
- 谷歌搜索框,搜索联想功能
- 窗口大小的 resize 。只需窗口调整完成后,计算窗口的大小,防止重复渲染
- 省市信息对应字母快速选择
4. vue 中使用
debounce(){
let timer = null;
return function(){
if(timer) {
clearTimeout(timer);
}else{
timer = setTimeout(this.func, 200);
}
}()
},
func(){
console.log("11111")
}