通俗解释
可以想象一个现实生活中常见的场景:进升降电梯。
![788a859274caf61dad3d7d5614ceee54.png](https://img-blog.csdnimg.cn/img_convert/788a859274caf61dad3d7d5614ceee54.png)
一般电梯设备检测到有人进入电梯的时候,会重新设定一个固定时间(假设为2s)再关闭电梯门,如果在这两秒内又有其他进入电梯,则会重新设定一个 2s 的倒计时。
其实这就是函数防抖的现实版本。这里的“函数”就是电梯关门的动作,所谓的“防抖”就是通过延迟执行来限制电梯关门的频率,并且在一定的时间内不管触发多少次都只会执行一次。可以想一想,如果没有对关门的动作做防抖限制,那么每进入一个人,电梯就会执行关门的动作,这是不是很费电呢?而且也不安全,门容易撞到人。
原始版本
这里给出函数防抖算法最通俗易懂的版本,看不懂来打我。
var debounce = {
tId: null,
// 实际进行业务处理的方法
handler: () => {
// 业务逻辑
},
// 程序初始化时调用的方法
process: () => {
clearTimeout(this.tId);
this.tId = setTimeout(() => {
this.handler();
}, 1000);
}
};
debounce.process();
升级版本
上面的版本在功能上没什么问题,但是代码有点长,略显繁琐。那么接下来实现它的精简版,也是目前业界比较通用的一个版本。
function debounce(method, context, timeout = 1000) {
clearTimeout(method.tId);
method.tId = setTimeout(() => {
method.call(context);
}, timeout);
}
前端工程中的实际应用
- 搜索引擎关键字推荐
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>函数防抖——在搜索引擎关键字推荐中的应用</title>
</head>
<body>
<input id="search-input" type="text" placeholder="请输入搜索关键字"/>
</body>
<script>
(function() {
function debounce(method, context, timeout = 1000) {
clearTimeout(method.tId);
method.tId = setTimeout(() => {
method.call(context);
}, timeout);
}
function handleInputChange() {
// 通过 debounce(handleInputChange, event),debounce 中的method.call 把 this 指向了 event
console.log('开始搜索:', this.target.value);
}
var $input = document.getElementById('search-input');
$input.addEventListener('input', (event) => {
debounce(handleInputChange, event);
});
})();
</script>
</html>
- 在 onresize 事件中的应用
众所周知,DOM 操作是非常昂贵的,如果我们在 onresize 事件处理程序中有对 DOM 的操作逻辑,那么在我们频繁调整浏览器窗口大小的时候,假如不做防抖处理,浏览器有可能会挂起,甚至崩溃。
例如:假设有一个<div/>
元素需要保持它的高度始终等于它的宽度。那么基于函数防抖算法我们可以这么实现:
function resizeDiv() {
var div = document.getElementById('myDiv');
div.style.height = div.offsetWidth + 'px';
}
resizeDiv(); // 页面初始化时让高度也等于宽度
window.onresize = function() {
debounce(resizeDiv);
}