前端魔法:防抖术,让你的网页操作如丝般顺滑

166 阅读3分钟

前言

当我们在开发过程中,经常会遇到用户点击一个按钮数次。对!你没猜错,就是抢红包!但是结果却是点一次和点n次,都是红包已被抢光。而且这样频繁点击,不仅仅是你手机屏幕受不了,后台也同样受不了。为了解决这个问题,我们需要引用一种机制来控制,所有这就是我们今天要讲的防抖概念。

什么是防抖?

防抖是一种前端优化技术,用于控制函数的执行频率,确保在连续触发某个事件时,只有最后一次触发会导致函数的执行。防抖的主要思想是延迟执行函数,只有在一定时间内没有新的触发事件发生时,才会执行函数。

防抖的应用场景

输入框搜索:避免用户每次输入都触发搜索请求,而是等待用户停止输入一小段时间后再执行搜索。

窗口大小调整:当用户调整浏览器窗口大小时,防抖可以确保在用户完成调整后执行相应的调整逻辑,而不是在每次窗口尺寸变化时都触发操作。

按钮点击:防止用户在短时间内多次点击按钮而触发多次事件处理函数,通常用于防止误操作。

如何实现防抖

下面我们来通过案例分析:

// 获取id为'btn'的按钮元素
let btn = document.getElementById('btn');
// 定义一个函数 send,用于模拟提交完成的操作
function send() {
    console.log('提交完成');
}
// 通过事件监听给按钮添加点击事件,使用防抖函数 debounce 包装 send 函数
btn.addEventListener('click', debounce(send, 1000));
function debounce(fn, delay) {
    let timer; 
    return function () {
        let args = arguments;
        // 保存当前函数执行时的 this 指向
        let _this = this;
        // 如果存在之前设置的定时器,清除它
        if (timer) clearTimeout(timer);
        // 设置一个新的定时器,在延迟时间(delay)之后执行传入的函数(fn)
        timer = setTimeout(function () {
            // 使用 call 方法执行传入的函数,并传入正确的上下文和参数
            fn.call(_this, ...args);
        }, delay);
    };
}

我们来分析这个案例中的代码:

btn.addEventListener('click', debounce(send, 1000));

通过 addEventListener方法给按钮添加了一个点击事件监听器。当按钮被点击时,调用debounce函数,将 send函数和防抖的延迟时间(1000毫秒)作为参数传入。

debounce(send, 1000) 返回一个新的函数,这个新函数在按钮点击后的 1000 毫秒内没有新的点击事件发生时,才会执行send函数。这样做的目的是为了防止按钮被快速连续点击时,频繁触发send函数,通过防抖确保在一段时间内只执行一次send函数,以提高性能和避免不必要的重复操作。

timer = setTimeout(function () {
    fn.call(_this, ...args);
}, delay);

设置一个新的定时器,在延迟时间(delay)之后执行传入的函数(fn)。使用call方法确保传入的函数在执行时具有正确的上下文和参数。

防抖的工作流程

1.每次调用防抖函数时,先清除之前设置的定时器(如果存在)。

2.设置一个新的定时器,延迟时间过后执行原始函数。

3.如果在延迟时间内再次调用了防抖函数,会清除之前的定时器,重新设置一个新的定时器,重复上述步骤。

4.这样做的结果是,只有在最后一次调用后的一段时间内没有新的调用时,才会执行原始函数。

总结

防抖也不是万能的,也会有一定缺点,比如会延迟函数的执行时间,在一些实时性要求较高的场景需谨慎使用。

感谢您的阅读,点赞关注作者更新更多后续