原创
手写函数防抖
什么是函数防抖?
函数防抖,顾名思义,就是当持续触发事件时,只有事件停止触发 n 秒后才执行,如果这 n 秒内又触发了事件,则会重新计算延时。
函数防抖的应用场景
- 表单验证:在用户连续输入时,仅在用户停止输入一段时间后才进行验证,减少验证的频率。
- 搜索建议:用户在搜索框中输入时,延迟发送请求获取建议,直到用户停止输入一段时间。
- 窗口大小调整:当调整浏览器窗口大小时,只在调整停止后重新计算布局或更新样式。
实现原理
函数防抖的核心在于使用setTimeout来延迟函数的执行,并在每次调用时取消之前的延时调用,从而确保只有最后一次操作能触发函数执行。
手写防抖函数
下面是一个简单实用的防抖函数实现:
JavaScript
123456789101112131415
function debounce(func, wait) {
let timer;
// 用于存储setTimeout的返回值,以便于 clearTimeout
return function(...args) {
if (timer) {
// 如果已有定时器,则清除它
clearTimeout(timer);
}
timer = setTimeout(() => {
// 重新设置定时器
func.apply(this, args);
// 在延迟时间结束后执行原函数
}, wait);
};
}
在这个实现中,debounce函数接收两个参数:一个是需要防抖处理的函数func,另一个是延迟执行的时间wait(单位为毫秒)。内部返回一个新的函数,这个新函数会在每次被调用时清除之前的延时调用,并重新设置一个延时执行的定时器。当延时期限到达且没有新的调用时,原始函数func才会被执行。
优化
相比于一个周期最后一次触发后,等待一定的时间在执行目标函数,我们需要实现一个在一个周期内容第一次触发,就立即执行一次,然后在触发后,等待一定的时间,才执行目标函数。这样的体验会更好。
JavaScript
1234567891011121314151617181920212223
function debounce(fn, wait, immediate) {
let timer;
let _debounce = function () {
let context = this;
if (timer) {
clearTimeout(timer);
}
if (immediate) {
let callNow = !timer;
if (callNow) {
func.apply(context, arguments);
}
timer = setTimeout(function () {
timer = null;
}, wait);
} else {
timer = setTimeout(function () {
func.apply(context, arguments);
}, wait);
}
}
return _debounce;
}
期待你的捷足先登






