什么是防抖和节流?有什么区别?如何实现?
- 什么是防抖和节流
- 区别
- 为什么要有防抖和节流
- 应用场景
- JavaScript 中的实现方式
什么是防抖和节流
- 防抖
n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时。
- 节流
n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效。
区别
在
单位时间内
内疯狂点击一个按钮,如果使用了防抖则会只执行一次,而你使用了节流则会每隔一段时间执行一次,这个时间可以自己来掌控。
为什么要有防抖和节流
本质上是优化高频率执行代码的一种手段:
如:浏览器的 resize
、scroll
、keypress
、mousemove
等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用 防抖(debounce) 和 节流(throttle) 的方式来减少调用频率。
应用场景
防抖 在连续的事件,只需触发一次回调的场景有:
搜索框搜索输入。只需用户最后一次输入完,再发送请求;
手机号、邮箱验证输入检测;
窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。节流 在间隔一段时间执行一次回调的场景有:
滚动加载,加载更多或滚到底部监听;
搜索框,搜索联想功能。
JavaScript 中的实现方式
这里使用闭包的方式来实现 防抖 和 节流,注意使用
apply()
函数来调整 this
的指向。
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>防抖&节流</title>
</head>
<body>
<div>
<div>
<label>防抖</label>
</div>
<button id="add">防抖加法器</button>
<label id="count">真实触发了0次</label>
</div>
<div style="margin-top: 20px;">
<div>
<label>节流</label>
</div>
<button id="throttleAdd">节流加法器</button>
<label id="throttleCount">真实触发了0次</label>
</div>
<script lang="js">
/* 防抖 */
let addBtn = document.getElementById("add");
let count = document.getElementById("count");
let n = 0;
function addOne() {
n = n + 1;
count.innerHTML = `真实触发了${n}次`;
}
function debounce(fun, time) {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fun.apply(this, arguments);
}, time);
};
}
addBtn.addEventListener("click", debounce(addOne, 2000));
/* 节流 */
let throttleAddBtn = document.getElementById("throttleAdd");
let throttleCount = document.getElementById("throttleCount");
let m = 0;
function addThrottl() {
m = m + 1;
throttleCount.innerHTML = `真实触发了${m}次`;
}
function throttle(fun, time) {
let timer = 0;
return function () {
let currentTime = new Date();
if (currentTime - timer > time) {
fun.apply(this, arguments);
timer = currentTime;
}
};
}
throttleAddBtn.addEventListener("click", throttle(addThrottl, 2000));
</script>
</body>
</html>