import { CacheUtil } from './CacheUtil';
import { DateUtil } from './DateUtil';
/**
* 节流、防抖工具类(用于点击事件,防止按钮被重复点击)
*
* @author 鸿蒙布道师
* @since 2025/04/07
*/
export class ClickUtil {
private static throttleTimeoutID: number | null = null; // 节流 timeout ID
private static flag: boolean = false; // 节流标志位,true 表示已进入执行状态
private static defaultId: string = DateUtil.getTodayTime().toString(); // 防抖默认 ID
/**
* 节流:在一定时间内,只触发一次
*
* @param func 要执行的回调函数
* @param wait 延时的时间,默认为 1000 毫秒
* @param immediate 是否立即执行,默认为 true
* - true: 立即执行第一次调用
* - false: 等待指定时间后执行
*/
static throttle(func: () => void, wait: number = 1000, immediate: boolean = true): void {
if (immediate) {
// 如果未处于节流状态,则立即执行
if (!ClickUtil.flag) {
ClickUtil.flag = true;
typeof func === 'function' && func();
ClickUtil.throttleTimeoutID = setTimeout(() => {
ClickUtil.flag = false;
if (ClickUtil.throttleTimeoutID !== null) {
clearTimeout(ClickUtil.throttleTimeoutID);
ClickUtil.throttleTimeoutID = null;
}
}, wait);
}
} else {
// 如果未处于节流状态,则等待指定时间后执行
if (!ClickUtil.flag) {
ClickUtil.flag = true;
ClickUtil.throttleTimeoutID = setTimeout(() => {
ClickUtil.flag = false;
typeof func === 'function' && func();
if (ClickUtil.throttleTimeoutID !== null) {
clearTimeout(ClickUtil.throttleTimeoutID);
ClickUtil.throttleTimeoutID = null;
}
}, wait);
}
}
}
/**
* 防抖:一定时间内,只有最后一次操作,再过 wait 毫秒后才执行函数
*
* @param func 要执行的函数
* @param wait 延时的时间,默认为 1000 毫秒
* @param clickId 设置的点击事件 ID,用于区分多个点击事件,不传则使用默认 ID
*/
static debounce(func: () => void, wait: number = 1000, clickId: string = ClickUtil.defaultId): void {
const cacheKey = `ClickUtil_debounce_timeoutID_${clickId}`;
const cachedTimeoutID = CacheUtil.get<number>(cacheKey); // 获取缓存的 timeout ID
// 清除之前的定时器
if (cachedTimeoutID !== undefined && cachedTimeoutID !== null) {
clearTimeout(cachedTimeoutID);
}
// 设置新的定时器
const timeoutID = setTimeout(() => {
typeof func === 'function' && func();
CacheUtil.remove(cacheKey); // 执行后清除缓存
}, wait);
// 缓存当前的 timeout ID
CacheUtil.put<number>(cacheKey, timeoutID);
}
}
代码如下:
import { CacheUtil } from './CacheUtil';
import { DateUtil } from './DateUtil';
/**
* 节流、防抖工具类(用于点击事件,防止按钮被重复点击)
*
* @author 鸿蒙布道师
* @since 2025/04/07
*/
export class ClickUtil {
private static throttleTimeoutID: number | null = null; // 节流 timeout ID
private static flag: boolean = false; // 节流标志位,true 表示已进入执行状态
private static defaultId: string = DateUtil.getTodayTime().toString(); // 防抖默认 ID
/**
* 节流:在一定时间内,只触发一次
*
* @param func 要执行的回调函数
* @param wait 延时的时间,默认为 1000 毫秒
* @param immediate 是否立即执行,默认为 true
* - true: 立即执行第一次调用
* - false: 等待指定时间后执行
*/
static throttle(func: () => void, wait: number = 1000, immediate: boolean = true): void {
if (immediate) {
// 如果未处于节流状态,则立即执行
if (!ClickUtil.flag) {
ClickUtil.flag = true;
typeof func === 'function' && func();
ClickUtil.throttleTimeoutID = setTimeout(() => {
ClickUtil.flag = false;
if (ClickUtil.throttleTimeoutID !== null) {
clearTimeout(ClickUtil.throttleTimeoutID);
ClickUtil.throttleTimeoutID = null;
}
}, wait);
}
} else {
// 如果未处于节流状态,则等待指定时间后执行
if (!ClickUtil.flag) {
ClickUtil.flag = true;
ClickUtil.throttleTimeoutID = setTimeout(() => {
ClickUtil.flag = false;
typeof func === 'function' && func();
if (ClickUtil.throttleTimeoutID !== null) {
clearTimeout(ClickUtil.throttleTimeoutID);
ClickUtil.throttleTimeoutID = null;
}
}, wait);
}
}
}
/**
* 防抖:一定时间内,只有最后一次操作,再过 wait 毫秒后才执行函数
*
* @param func 要执行的函数
* @param wait 延时的时间,默认为 1000 毫秒
* @param clickId 设置的点击事件 ID,用于区分多个点击事件,不传则使用默认 ID
*/
static debounce(func: () => void, wait: number = 1000, clickId: string = ClickUtil.defaultId): void {
const cacheKey = `ClickUtil_debounce_timeoutID_${clickId}`;
const cachedTimeoutID = CacheUtil.get<number>(cacheKey); // 获取缓存的 timeout ID
// 清除之前的定时器
if (cachedTimeoutID !== undefined && cachedTimeoutID !== null) {
clearTimeout(cachedTimeoutID);
}
// 设置新的定时器
const timeoutID = setTimeout(() => {
typeof func === 'function' && func();
CacheUtil.remove(cacheKey); // 执行后清除缓存
}, wait);
// 缓存当前的 timeout ID
CacheUtil.put<number>(cacheKey, timeoutID);
}
}