一个DOM元素绑定了事件,如果不断地触发事件,函数会频发地执行,这样会消耗大量的性能。这时候,节流和防抖就是很好的解决方案。
const myDiv = document.getElementById("click");
const mySpan = document.getElementById("show");
let num = 0;
function count () {
num++;
mySpan.innerText = num;
}
myDiv.onclick = count;
防抖(debounce)
防抖,就是触发事件之后,在第 n 秒时执行函数,如果在 n 秒内再次触发事件,就会重新计算函数的执行时间。
防抖有两个版本,一个是立即执行,另外一个是延迟执行。
立即执行:触发事件之后,立即执行函数,如果在 n 秒内再次触发,函数不执行。
function debounceLater (func,wait) {
let timer = null;
return function () {
// 判断timer有没有赋值,无赋值,证明无触发事件,有赋值,证明触发了事件
if(timer){
// 有赋值,函数不能执行,立即清除timer,重新计时,延时清除timer
clearTimeout(timer);
}else {
// 没有赋值,马上执行函数,给timer赋值,延时清除timer
func();
}
// 把都需要执行的部分提取出来
timer = setTimeout(function () {
timer = null;
}, wait)
}
}
myDiv.onclick = debounceLater(count, 1000);
非立即执行:触发事件之后,在第 n 秒时执行函数,如果在 n 秒内再次触发,计时器重新计时。
function debounceRightNow (func, wait) {
let timer = null;
return function () {
// 判断timer有没有赋值,如果触发了事件,timer会被赋值。
if(timer){
//timer被赋值了,那就清除计时器,重新计时
clearTimeout(timer);
}
// 延迟执行
timer = setTimeout(function () {
func();
}, wait)
}
}
myDiv.onclick = debounceRightNow(count, 1000);
节流(throttle)
节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
function throttle (func, wait) {
// 初始化时间 before = 0 表示还没有触发过事件
let before = 0;
return function () {
let now = Date.now();
if(now - before > wait){
func();
before = now;
}
}
}
myDiv.onclick = throttle(count, 1000);