在写聊天页面的时候有个滚动到底部,在弹出键盘,打开表情,打开更多,发送消息等很多场景下需要重新计算底部高度和滚动到最底部的操作。导致连续调用函数来计算,导致了效率问题,页面极其卡顿。因为只关心最后一次的结果,那么可以使用防抖来解决,什么是防抖呢?
防抖(debounce)函数在许多场景中都非常有用,比如用户在搜索框中输入文本时,我们可能不想立即处理用户的输入,而是希望在用户停止输入一段时间后再进行处理。这样可以避免不必要的处理,从而提高性能。
使用JS防抖函数的前提条件主要有以下几点:
函数防抖很多时候是会降低用户体验的而不是没有代价的。所以需要注意的是,防抖函数并不适用于所有场景。比如,对于一些需要实时反馈的场景,如打字效果,就不适合使用防抖函数。我这里的聊天滚动场景就非常的合适。
// 定义一个名为"debounce"的函数,它接受两个参数:func(要防抖的函数)和 delay(延迟的毫秒数)
function debounce(func, delay) {
// 声明一个变量timeoutId,用于存储setTimeout返回的定时器ID,初始值为null
let timeoutId;
// 返回一个新的函数,该函数作为debounce函数的结果,它接受任意数量的参数,并返回一个新的函数
// 这个新的函数将作为最终的防抖函数,它将在指定的延迟时间后执行func函数
return function() {
// 将当前对象(this)赋值给变量context,将当前传入的参数列表赋值给变量args
const context = this;
const args = arguments;
// 清除之前设置的定时器(如果有的话),以避免在延迟期间再次触发执行
clearTimeout(timeoutId);
// 使用setTimeout设置一个新的定时器,在延迟时间后执行func函数
// 在延迟期间内再次触发返回的函数时,会清除之前的定时器并重新设置,以确保只有最后一次触发后才会等待延迟时间结束后执行func
timeoutId = setTimeout(function() {
// 在延迟时间结束后,使用apply方法调用func函数,并将context和args作为参数传递给它
func.apply(context, args);
}, delay);
};
}
// 定义一个示例用法:创建一个防抖函数myEfficientFn,它将在1000毫秒(1秒)后执行指定的函数,并打印一条消息到控制台
const myEfficientFn = debounce(function() {
console.log('事件触发!');
}, 1000); // 1000毫秒后执行指定的函数,并打印一条消息到控制台
// 频繁触发事件,比如用户在搜索框中输入文本,调用防抖函数myEfficientFn
myEfficientFn(); // 在用户停止输入后,只打印一次"事件触发!"