功能
均采用闭包方式实现,节流使用时间戳Date.now()
原理,防抖使用定时器setTimeout
实现
时间戳可以实现时间间隔开头生效,定时器可以实现时间间隔末尾生效
防抖
多次重复触发,只生效最后一次触发。如果连续双击,只有最后一下会生效。
节流
一段时间间隔,只在开头生效。如果连续双击,只有第一下会生效。
优化?
网上有些优化版,节流是在时间间隔的开头和结尾都会生效,防抖是开头生效,最后触发那次的计时结束再生效一次。如果这样的话,双击就会生效两次,这不是我需要的常规的防抖节流,对于特殊场景下,可能才会需要这样的优化吧
代码
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
<button class="btn1">节流,一段时间内只触发一次</button>
<button class="btn2" style="margin-top: 30px">防抖,点击重复计时</button>
<script>
// 节流:短时间多次触发,重新计时
// 防抖:短时间重复触发,只执行一次
document
.querySelector(".btn1")
.addEventListener("click", throttle(handleClick("节流"), 1000));
document
.querySelector(".btn2")
.addEventListener("click", debounce(handleClick("防抖"), 1000));
function handleClick(text) {
let temp = 0;
return function () {
if (text) {
console.log(text);
}
console.log(temp);
temp++;
};
}
function throttle(fn, delay) {
let t1 = 0;
return function (...args) {
let t2 = Date.now();
if (t2 - t1 >= delay) {
fn.apply(this, args);
t1 = t2;
}
};
}
function debounce(fn, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
</script>
</body>
</html>