防抖

防抖

防抖很常见啊,但是 8.2 米哈游一面就没写出来可用的版本 🥲,所以总结记录一下防抖的相关知识

是什么

在一定时间间隔内,将多次触发变成一次触发

其实开发会遇到很多需要使用他的场景,比如有个按钮,点一下就发一次请求,如果用户一直点击,就会高频发请求,这会造成资源浪费。以及我们想在浏览器滚动事件添加一个回调函数,一滚动就出发了特别多次,希望可以降低一下频率,不然会影响性能。这个时候就可以用到防抖了,当用户点击频率过高,只以最后一个为准,就只发一次请求。

实现

其实思路也很简单,点击 -> 开启一个定时器,到时间执行回调函数 -> 如果还没到时间又点了就清除旧的定时器,开一个新的定时器重新计时即可

这是一个点击的场景,点击频率是没有限制的

<button>点我啊</button>

<script>
const btn = document.querySelector('button')
const fn = () => {
console.log('点了')
}
btn.onclick = fn
</script>

那么基于思路实现一个简单的防抖,其中要注意处理 this 指向的问题

function debounce(callback, delay) {
let timer = null
return function (...args) {
clearTimeout(timer)
timer = setTimeout(() => {
callback.apply(this, args)
}, delay)
}
}
btn.onclick = debounce(fn, 500)

现在还有一个问题,如果用没有高频点击,他的行为也会被延迟,比如现在点,500ms 后才会触发 callback,这也会影响体验,我们可以通过一个参数来控制是否要立刻执行。

function debounce(callback, delay, immediate = false) {
let timer = null
return function (...args) {
const runNow = immediate && !timer

clearTimeout(timer)
timer = setTimeout(() => {
callback.apply(this, args)
clearTimeout(timer)
}, delay)

if (runNow) {
callback.apply(this, args)
clearTimeout(timer)
}
}
}
btn.onclick = debounce(fn, 500, true)

场景

大多用于按钮提交、实时搜索优化、窗口调整事件处理