什么是防抖
防抖就是在触发事件后,不会立即执行,而是在规定时间以后才会执行;
如果在规定时间内再次触发事件,那么会重新开始计时。
应用场景
- 表单验证
- 按钮提交
- 输入框查询
- scroll 事件滚动触发
- 浏览器窗口缩放,resize 事件
实现功能
- 绑定的是一个 function,所以要 return 一个 function
- this 指向,如果不用箭头函数,还要在定时器外部绑定 this
- arguments 获取参数,如果不用箭头函数,还要在定时器外部绑定 arguments
- 增加条件判断是否立即执行(触发即执行,然后 n 秒内触发不执行,n 秒后触发再次立即执行)
- 返回值(如果立即执行,可以获取返回值)
- 取消防抖(cancel 方法,清除定时器,为了避免闭包导致的内存泄漏,再把 timer 设置为 null)
基础版
function debounce(fn, wait) {
let timer;
return function () {
if (timer) clearTimeout(timer);
const _this = this;
const args = arguments;
timer = setTimeout(() => {
fn.apply(_this, args);
}, wait);
};
}
进阶版
function debounce(fn, wait, immediate) {
let timer, result;
return function () {
if (timer) clearTimeout(timer);
const _this = this;
const args = arguments;
if (immediate) {
if (!timer) result = fn.apply(_this, args);
timer = setTimeout(() => {
timer = null;
}, wait);
} else {
timer = setTimeout(() => {
fn.apply(_this, args);
}, wait);
}
return result;
};
}
增强版
function debounce(fn, wait, immediate) {
let timer, result;
function debounced() {
if (timer) clearTimeout(timer);
const _this = this;
const args = arguments;
if (immediate) {
if (!timer) result = fn.apply(_this, args);
timer = setTimeout(() => {
timer = null;
}, wait);
} else {
timer = setTimeout(() => {
fn.apply(_this, args);
}, wait);
}
return result;
}
debounced.cancel = function () {
clearTimeout(timer);
timer = null;
};
return debounced;
}
验证
<input type="text" id="search">
<button id="cancel">取消防抖</button>
const inputEle = document.getElementById("search");
const buttonEle = document.getElementById("cancel");
function searchHandler(e) {
console.log(e);
console.log(inputEle.value);
return "123";
}
let handler = debounce(searchHandler, 10000);
buttonEle.addEventListener("click", handler.cancel);
inputEle.addEventListener("keyup", handler);