一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 在给DOM绑定事件时,有些事件我们是无法控制触发频率的。 如鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。 在实时检查输入时,如果我们绑定onkeyup事件发请求去服务端检查,用户输入过程中,事件的触发频率也会很高,会导致大量的请求发出,响应速度会大大跟不上触发。
针对此类快速连续触发和不可控的高频触发问题,debounce 和 throttling 给出了两种解决策略
-
- 对于短时间内连续触发的事件(如滚动事件),防抖的含义就是让某个时间期限(如1000毫秒)内,事件处理函数只执行一次。
函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。如下图,持续触发scroll事件时,并不执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发scroll事件。
防抖 debounce
- 监听一个输入框的,文字变化后触发 change事件
- 直接用keyup事件,则会频繁触发change事件
防抖
: 用户输入结束或暂停时
,才会触发change事件
const input = document.getElementById('input')
let timer = null
input.addEventListerner('keyup',function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(()=>{
//模拟触发change事件
console.log(input.value)
//清空定时器
timer = null
},500)
})
//防抖
function debounce(fn,delay){
let timer = null //借助闭包,timer是在闭包中
return function() {
if(timer){
clearTimeout(timer) //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时
}
timer = setTimeout(fn,delay) // 简化写法
}
}