防抖
当连续不断的触发事件函数时,先直接触发一次或不触发,在触发停止的一段时间后执行一次
利用闭包
非立即执行
function debounce(func, await) {
let timer;
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, arguments);
}, await);
};
}
立即执行
function debounce(func, await) {
let timer;
return function () {
计时器一旦开启timer便始终为一个正整数
if (timer) {
clearTimeout(timer);
}
let doNow = !timer;
timer = setTimeout(() => {
timer = null;
}, await);
if (doNow) {
func.apply(this, arguments);
}
};
}
结合版
function debounce(func, await, immediate) {
let timer;
return function () {
if (timer) {
clearTimeout(timer);
}
if (immediate) {
let doNow = !timer;
timer = setTimeout(() => {
timer = null;
}, await);
if (doNow) {
func.apply(this, arguments);
}
} else {
timer = setTimeout(() => {
func.apply(this, arguments);
}, await);
}
};
}
节流
当持续不停的触发事件函数时,每过一段时间便会触发一次
利用闭包
时间戳版
function debounce(func, interval) {
注意给prev一个初始值
let prev = 0;
return function () {
now = Date.now();
if (now - prev >= interval) {
func.apply(this, arguments);
prev = now;
}
};
}
计时器版
function debounce(func, interval) {
let timer;
return function () {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, interval);
}
};
}
结合版
function debounce(func, interval, type) {
if (type === 1) {
let prev = 0;
return function () {
let now = Date.now();
if (now - prev >= interval) {
prev = now;
func.apply(this, arguments);
}
};
}
if (type === 2) {
let timer;
return function () {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, arguments);
timer = null;
}, interval);
}
};
}
}
使用
dom.onmousemove = debounce(func, 1000);
this
指向dom
元素本身,arguments[0]
指向事件参数e