大家好,我是梅巴哥er
。今天一起来搞懂JS的节流和防抖。不再犯难!
什么是节流和防抖?
- 节流:比如点击按钮让盒子移动50px。第一次点击按钮,盒子开始移动,然后在盒子移动完这50px的距离前,你接着不停的点击按钮,但是盒子并不会移动超过50px的距离。等移动到50px的位置后,你再点击按钮,才能再次让盒子移动下一个50px。总结:第一次操作的时候,开始执行。第一次执行结束前,再怎么操作都无效。就像你要喝水,打开饮水机水龙头接了一杯热水。就赶紧关掉饮水机水龙头。等你要倒下一杯水的时候再打开水龙头放水,不会一直开着。这样节省水流,所以叫节流。
- 防抖:还拿发送验证码为例。上来就不停的点按钮,结果它就不发送验证码。等你不点击了,它开始发送验证码。总结:一直操作都无效,在最后一次操作时,开始执行。连续操作多次,都只会在最后一次操作才开始执行。防止手抖不停的操作,所以叫防抖。
节流和防抖有啥区别?思路是什么?
-
区别:
- 节流是一段时间内的第一次点击有效,其他点击都无效。
- 防抖是一段时间内的最后一次点击有效,其他点击都无效。
-
思路:
-
节流思路:给操作函数加一个节流阀。
- 函数执行前,先打开节流阀。
- 函数开始执行时,就关闭节流阀。
- 函数执行结束,再打开节流阀。
-
防抖思路:我先定一个推迟执行的时间(定时器),在这个时间内,你如果操作5次,我就把前面4次的操作都给清除掉(清除定时器触发的函数),不让前面4次的操作去执行。等推迟的时间到了,再执行你第5次的操作。
-
节流案例
效果图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节流</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 100px;
height: 100px;
background-color: pink;
text-align: center;
line-height: 100px;
}
#btn {
margin-top: 5px;
}
</style>
</head>
<body>
<div id="box"></div>
<button id="btn">移动</button>
<script>
var flag = true; // ①初始状态,打开节流阀
var num = 0; // 初始化点击的次数
var box = document.getElementById('box');
var btn = document.getElementById('btn');
function animate(obj, target) {
// 移动一大步的动画函数
// target是移动一大步的目标距离
clearInterval(obj.timer);
function move() {
// 移动一小步
// step是移动一小步的距离
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if(obj.offsetLeft === target) {
flag = true; // ③移动到目标位置后,打开节流阀
}
obj.style.marginLeft = obj.offsetLeft + step + 'px';
}
obj.timer = setInterval(move, 50); // 50毫秒移动一小步
}
btn.addEventListener('click', function() {
if(flag) {
// 如果节流阀是打开的,执行下面的代码
num++;
flag = false; // ②点击一次后,关闭节流阀
animate(box, num*50);
}
console.log(num, flag, box.offsetLeft) // 查看点击时的状态
})
</script>
</body>
</html>
防抖案例
效果图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>防抖</title>
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 100px;
height: 100px;
background-color: pink;
}
#btn {
margin-top: 5px;
margin-left: 20px;
}
</style>
</head>
<body>
<div id="box"></div>
<button id="btn">防抖</button>
<script>
function debounce(fn, delay) {
// 防抖函数
let handle;
return function (e) {
// 取消之前的延时调用
clearTimeout(handle);
handle = setTimeout(() => {
fn(e);
}, delay);
}
}
function move() {
box.style.marginLeft = box.offsetLeft + 50 + 'px';
}
var box = document.getElementById('box');
var btn = document.getElementById('btn');
btn.addEventListener('click', debounce(move, 500))
</script>
</body>
</html>