防抖和节流都是为了解决高频率触发事件而导致的性能问题。
防抖: 在一定时间内,如果事件被触发多次,则只执行最后一次。比如说,当用户连续快速点击按钮时,我们只需要执行最后一次点击事件即可。
节流: 在一定时间内,只执行一次事件。比如说,当用户连续快速滚动页面时,我们只需要在一定时间内执行一次滚动事件即可。
基本实现原理
/**
* 最浅显易懂的 防抖节流
* javascript 函数 节流 防抖的简易封装
* 使用 setTimeout 定时器 实现
* 防抖: 在点击结束一段时间之后 函数才开始执行
* 节流: 在一段时间之内, 函数只能执行一次
*/
let timer, // 使用定时器
num, // 计算点击次数
flag = true, // boolean 控制函数是否执行
timeout = 2000; // 节流防抖的时间间隔
// 想要节流的函数
function start() {
// 要执行的函数
console.log("success");
}
// 节流函数
function throttle() {
if (flag) {
// 使用 flag 变量 控制函数是否执行
flag = !flag; // 改变 变量 让 timeout 时间之内 函数不执行
start(); // 触发函数
timer = setTimeout(() => {
// 使用定时器 timeout 时间之后 函数可以再次执行
flag = !flag; // timeout 时间之后 让函数可以再次执行
}, timeout);
}
}
// 防抖函数
function debounce() {
timer = clearTimeout(timer); // 连续点击 清除定时器 让定时器触发 timeout 时间一直刷新
timer = setTimeout(() => {
// 使用定时器, 让函数在点击 timeout 时间之后 开始执行
start();
}, timeout);
}
// 节流函数
function throttle() {
num++;
if (flag) {
// 使用 flag 变量 控制函数是否执行
flag = !flag;
start();
timer = setTimeout(() => {
num = 0;
flag = !flag;
}, timeout);
}
if (num > 6) {
alert("您的点击太过频繁, 歇一会儿吧");
}
}
function debounce() {
if (num > 6) {
alert("您的点击太过频繁, 歇一会儿吧");
}
timer = clearTimeout(timer); // 连续点击 清除定时器 让定时器触发 timeout 时间一直刷新
timer = setTimeout(() => {
// 使用定时器, 让函数在点击 timeout 时间之后 开始执行
start();
num = 0;
}, timeout);
}
class 类封装以及使用方法
class DebounceThrottle {
constructor(delay) {
this.delay = delay;
this.timer = null;
}
throttle(fn, ...args) {
if (!this.timer) {
fn.apply(this, args);
this.timer = setTimeout(() => {
this.timer = null;
}, this.delay);
}
}
debounce(fn, ...args) {
clearTimeout(this.timer);
if (!this.timer) {
this.timer = setTimeout(() => {
fn.apply(this, args);
this.timer = null;
}, this.delay);
}
}
}
export default { DebounceThrottle };
// 在其他文件引入
const DebounceThrottle = require('./DebounceThrottle');
// 或者
import DebounceThrottle from './DebounceThrottle';
function start() {
console.log("Throttle function is running");
}
// 使用方法
const debounceThrottle = new DebounceThrottle(2000);
// 定时器模拟多次点击间隔
setInterval(() => {
debounceThrottle.debounce(start); //
debounceThrottle.throttle(start); //
}, 2400);