节流
在单位时间内,将多次事件按照时间做平均分配触发
案例
在这个场景中,设置点击按钮之后加一。若是用户不断点击,则增长很快。所以我们想让他慢一些,即使用户在短时间内不断点击多次,也只设置每500ms执行一次。
解决办法:节流
//节流函数(也是一个高阶函数)
function throttle(fn, time = 500) {
let timer;
return function (...args) {
//执行到这一步,说明距离上次事件执行完成已经过去了time秒
if (timer == null) {
//把fn的this指向调用本函数的对象
fn.apply(this, args);
timer = setTimeout(() => {
//时间到了,就重置为null,说明可以再次执行事件
timer = null;
}, time)
}
}
}
const btn = document.querySelector('div');
const circle = document.querySelector('span');
btn.onclick = throttle(function (e) {
circle.innerHTML = parseInt(circle.innerHTML) + 1;
btn.className = 'fade';
setTimeout(() => btn.className = '', 250);
});
场景
-鼠标不断点击触发:mousedown事件
防抖
- 如果一直被触发,则此次的触发会将上一次触发的定时器给清除,然后重新开启一个定时器,重新开始计时
- 等到时间到了才会执行回调函数
- 也就是:多次触发,指定时间内再次触发则上次无效,只有最后一次有效(多次事件一次响应)
function debounce(callback, time) {
// 定时器变量
let timeId = undefined;
// 返回一个函数
return function () {
if (timeId !== undefined) {
// 清空定时器
clearTimeout(timeId);
}
// 启动定时器
timeId = setTimeout(() => {
// 执行回调
callback(...arguments);
// 执行完了重置id
timeId = undefined;
}, time);
};
}
let input = document.querySelector("input");
input.onkeydown = debounce(function (e) {
console.log(e.keyCode);
}, 1000);
场景
- 当搜索框输入时联想可能的情况,需要用到防抖,等到一定时间内停止输入了再搜索,可以减少http发送请求的次数。
- mousemove事件的监听(监听鼠标最终定住的位置)