什么是防抖和节流?有什么区别?如何实现?

JavaScript 中防抖和节流的概念

定义

防抖(Debounce)是指当某个事件被触发后,在设定的时间内如果没有再次触发该事件,则执行相应的操作;如果在这段时间内又触发了该事件,则重新计时。
节流(Throttle)则是指在一定时间内只允许某件事情发生一次或者几次,通常用于控制高频事件的触发频率。


区别

特性防抖节流
核心概念延迟一段时间后再执行回调函数,期间多次触发会重置定时器在固定时间段内最多执行一次回调
适用场景用户输入完成后的延迟处理(如搜索框自动补全)、窗口调整完成后触发某些逻辑按钮点击、滚动条监控等需要限制调用次数的场景
触发时机只有最后一次触发才会生效时间段内的第一次或指定周期触发

实现方法

防抖实现

以下是基于 setTimeout 的简单防抖函数实现:

function debounce(func, delay) {
    let timer;
    return function (...args) {
        clearTimeout(timer);
        timer = setTimeout(() => func.apply(this, args), delay);
    };
}

此代码片段中,每次调用返回的新函数都会清除之前的定时器,并设置一个新的定时器。

节流实现

以下是基于时间戳的节流函数实现:

function throttle(func, limit) {
    let lastFunc;
    let lastRan;
    return function () {
        const context = this;
        const args = arguments;
        if (!lastRan) {
            func.apply(context, args);
            lastRan = Date.now();
        }
        else {
            clearTimeout(lastFunc);
            lastFunc = setTimeout(function () {
                if ((Date.now() - lastRan) >= limit) {
                    func.apply(context, args);
                    lastRan = Date.now();
                }
            }, limit - (Date.now() - lastRan));
        }
    };
}

在此代码中,只有当前时间和上次运行时间之间的差值大于等于设定的阈值时才执行函数。


示例代码对比

防抖示例

假设有一个按钮点击事件,我们希望用户停止连续点击一秒之后再执行相应动作:

<button id="debounceBtn">Click Me</button>
<script>
    const button = document.getElementById('debounceBtn');
    
    function handleClick() {
        console.log('Button clicked!');
    }

    button.addEventListener('click', debounce(handleClick, 1000)); // 设置防抖时间为1秒
</script>
节流示例

对于鼠标滚轮事件,我们可以限制每秒钟最多触发一次:

<div style="height: 200vh;">Scroll me!</div>
<script>
    window.addEventListener('scroll', throttle(() => {
        console.log('Scrolled!');
    }, 1000)); // 设置节流时间为1秒
</script>

对比表格

属性防抖节流
目标确保事件结束后的一段时间内仅执行一次控制单位时间内某一事件的最大执行次数
典型应用场景文本输入框中的实时查询、浏览器窗口大小改变页面无限加载、拖拽过程中计算位置
性能影响更适合减少不必要的重复请求更适合降低高频率事件对系统的压力
首次触发行为不立即响应立即响应
最终触发行为如果持续触发不会被执行即使持续触发也会按设定间隔执行

栗子总结
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值