什么是防抖
以点击一个按钮为例,每点击一次按钮,会提交一次请求,如果在一定时间内(以500ms为例)再次点击,则会取消上一次的提交,并重新开始计时,如果500ms内没有再次提交,则会执行最后一次的提交。
防抖函数的实现
// 防抖函数
// fn: 传入的需要防抖的函数
// delay: 事件触发后,执行回调函数的时间间隔
function debounce(fn, delay) {
// 初始化定时器
let timer = null;
return function (...args) {
// 保存this指向
let _that = this;
// 如果存在定时器,则清除计时器重新计时
if (timer) {
clearTimeout(timer);
}
// 不存在计时器,则新建一个定时器
timer = setTimeout(function () {
fn.call(_that, ...args);
}, delay);
};
}
防抖函数的应用
<button id="btn">button</button>
<div>
点击次数 <span id="text">0</span>
</div>
<script>
// 初始化点击次数,用于查看点击了多少次
let num = 0
// 获取元素
const btn = document.querySelector("#btn");
const count = document.querySelector("#text");
// 执行的函数
function log(message) {
console.log("阿叶同志-----------------------------", message);
}
// 防抖函数
function debounce(fn, delay) {
let timer = null;
return function (...args) {
let _that = this;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
fn.call(_that, ...args);
}, delay);
};
}
// 将执行的函数增加防抖,返回新的函数
let logDebounce = debounce(log, 500);
btn.addEventListener("click", function() {
// 用于查看点击了多少次
count.innerHTML = ++num
// 点击按钮之后,执行增加防抖的log函数
logDebounce(10086)
});
</script>
实现效果如下,当我们连续点击button按钮时,不触发log事件,当我们停止点击500ms后触发log事件,避免了多次触发log事件的情况。
什么是节流
以点击一个按钮为例,每点击一次按钮,会提交一次请求。在一定时间内,不管发生了点击事件,都只会提交一次请求。
节流的实现
// 节流函数
// fn: 传入的需要节流的函数
// delay:触发时间的间隔
function throttle(fn, delay) {
// 用来保存上一次触发函数的时间
let last;
return function (...args) {
// 保存this指向
let _this = this;
// 获取当前点击的时间
let now = +new Date();
// 如果当前是第一次点击,则last为undefined,进入else,直接执行fn函数
if (!last) {
fn.call(_this, ...args);
last = now;
} else {
// 如果不是第一次点击,则判断当前点击的时间减去上一次点击的时间是否大于等于设定的时间间隔
// 如果大于时间间隔,执行fn函数并将当前的时间记录为下一次点击时的上一次点击时间
if (now - last >= delay) {
fn.call(_this, ...args);
last = now;
}
}
};
}
ps: 上述代码以下的逻辑可以优化成更优雅的方式
// 优化前的代码
if (!last) {
fn.call(_this, ...args);
last = now;
} else {
if (now - last >= delay) {
fn.call(_this, ...args);
last = now;
}
}
// 优化后的代码
if (!last || (last && now - last >= delay)) {
fn.call(_this, ...args);
last = now;
}
节流函数的应用
<button id="btn">button</button>
<div>点击次数 <span id="text">0</span></div>
<script>
// 初始化点击次数,用于查看点击了多少次
let num = 0;
// 获取元素
const btn = document.querySelector("#btn");
const count = document.querySelector("#text");
// 执行的函数
function log(message) {
console.log("阿叶同志-----------------------------", message, new Date);
}
// 节流函数
function throttle(fn, delay) {
let last;
return function (...args) {
let _this = this;
let now = +new Date();
// if (!last) {
// fn.call(_this, ...args);
// last = now;
// } else {
// if (now - last >= delay) {
// fn.call(_this, ...args);
// last = now;
// }
// }
if (!last || (last && now - last >= delay)) {
fn.call(_this, ...args);
last = now;
}
};
}
// 将执行的函数增加节流,返回新的函数
let logThrottle = throttle(log, 1000);
btn.addEventListener("click", function () {
// 用于查看点击了多少次
count.innerHTML = ++num;
// 点击按钮之后,执行增加防抖的log函数
logThrottle (10086);
});
</script>
实现效果如下,当我们连续点击button按钮时,在单位时间(本示例为1s)内,该log函数只能触发一次。
总结
以上就是防抖和节流的实现,防抖是事件发生后,在设定的间隔时间内,再次触发事件,则重新计时,直到两次触发的时间间隔大于等于设定的时间间隔,事件的执行函数才会执行。节流是在设定的时间间隔内,事件只会被触发一次。