带你读懂防抖和节流

带你读懂防抖和节流

推荐阅读文章

1. 防抖(debounce)

描述

实现代码

推荐阅读文章的实现:

采用两个参数:检测周期(“threshold”阈值)和一个布尔值(“execAsap”),指示信号应该发生在检测周期的开始(true)还是结束(false)。

var debounce = function (func, threshold, execAsap) {
    var timeout; // 保存计时器的id, 便于取消, 同时作为锁
    return function debounced () {
        var obj = this, args = arguments;
        
        function delayed () {
            if (!execAsap) // execAsap 为false,信号发生在检测周期的结束(false)
                func.apply(obj, args); // 执行
            timeout = null;  // 开锁
        };
        
        if (timeout)
            clearTimeout(timeout); // 当锁关闭时,清除上一个的定时器
        else if (execAsap) // execAsap 为true,信号发生在检测周期的开始(true)
            func.apply(obj, args); // 执行
        
 	    // 加锁,同时设置计时器id
        timeout = setTimeout(delayed, threshold || 100); 
    };
}

使用

document.onmousemove = debounce(function (e) {
    /* do something here, but only once after mouse cursor stops */
}, 250, false);

2. 节流(throttle)

描述

  • 推荐阅读文章提到:

    Throttling is the reduction in rate of a repeating event. Throttling is good for reducing mousemove events to a lesser, manageable rate, for instance.

    节流是指降低重复事件的发生率。例如,节流有利于将鼠标移动事件减少到一个较小的、可管理的速率。

    与防抖的区别

    The main difference between this and debouncing is that throttle guarantees the execution of the function regularly, at least every X milliseconds.

    这与防抖之间的主要区别在于,throttle保证了函数的定期执行,至少每X毫秒执行一次

  • underscore.js实现节流函数的描述

  • lodash.js实现节流函数的描述

  • mdn对Scroll事件节流的描述:

    由于 scroll 事件可被高频触发,事件处理程序不应该执行高性能消耗的操作,如 DOM 操作。而更推荐的做法是使用 requestAnimationFrame()setTimeout()CustomEvent 给事件节流。

实现代码

根据区别(这与防抖之间的主要区别在于,throttle保证了函数的定期执行,至少每X毫秒执行一次。)

只需修改防抖的实现代码的一部分,就可实现:

var throttle = function (func, threshold, execAsap) {
    var timeout; // 保存计时器的id, 便于取消, 同时作为锁
    return function debounced () {
        var obj = this, args = arguments;
        
        function delayed () {
            if (!execAsap) // execAsap 为false,信号发生在检测周期的结束(false)
                func.apply(obj, args); // 执行
            timeout = null;  // 区别:只有时间到后才开锁
        };
        
        // 区别:只有时间到后才开锁,才能进入if语句
        if (!timeout) {
            if (execAsap) // execAsap 为true,信号发生在检测周期的开始(true)
                func.apply(obj, args); // 执行
            // 加锁,同时设置计时器id
            timeout = setTimeout(delayed, threshold || 100); 
        }
    };
}

3. requestAnimationFrame

Window:requestAnimationFrame() 方法 - Web API 接口参考 | MDN (mozilla.org)

window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

总结

  • debounce: Grouping a sudden burst of events (like keystrokes) into a single one.

    debounce:将一些突发事件(如击键)分组为一个事件。

  • throttle: Guaranteeing a constant flow of executions every X milliseconds. Like checking every 200ms your scroll position to trigger a CSS animation.

    throttle:保证每X毫秒执行一次的恒定流量。就像每隔200毫秒检查一次滚动位置以触发CSS动画一样。

  • requestAnimationFrame: a throttle alternative. When your function recalculates and renders elements on screen and you want to guarantee smooth changes or animations. Note: no IE9 support.

    requestAnimationFrame:一个节流的替代方案。当您的函数在屏幕上重新计算和渲染元素,并且您希望保证平滑的更改或动画时。注意:不支持IE9。

    以上总结来自推荐阅读,再次强烈推荐阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值