js 防抖、节流

前言

在前端开发中会遇到一些频繁的事件触发,比如:

  1. window 的 resize、scroll
  2. mousedown、mousemove
  3. keyup、keydown
    ...

为了解决这个问题,一般有两种解决方案:

  1. debounce 防抖
  2. throttle 节流

防抖

防抖的原理就是:你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行,真是任性呐!

// 第一版
function debounce(func, wait) {
    var timeout;
    return function () {
        clearTimeout(timeout)
        timeout = setTimeout(func, wait);
    }
}
this

修改正fn函数的this指向问题

// 第二版
function debounce(func, wait) {
    var timeout;

    return function () {
        var context = this;

        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(context)
        }, wait);
    }
}
event 对象

avaScript 在事件处理函数中会提供事件对象 event,我们修改下 func 函数的

// 第三版
function debounce(func, wait) {
    var timeout;

    return function () {
        var context = this;
        var args = arguments;

        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(context, args)
        }, wait);
    }
}

节流

节流的原理很简单:

如果你持续触发事件,每隔一段时间,只执行一次事件。

根据首次是否执行以及结束后是否执行,效果有所不同,实现的方式也有所不同。
我们用 leading 代表首次是否执行,trailing 代表结束后是否再执行一次。

关于节流的实现,有两种主流的实现方式,一种是使用时间戳,一种是设置定时器。

使用时间戳

让我们来看第一种方法:使用时间戳,当触发事件的时候,我们取出当前的时间戳,然后减去之前的时间戳(最一开始值设为 0 ),如果大于设置的时间周期,就执行函数,然后更新时间戳为当前的时间戳,如果小于,就不执行。

// 第一版
function throttle(func, wait) {
    var context, args;
    var previous = 0;

    return function() {
        var now = +new Date();
        context = this;
        args = arguments;
        if (now - previous > wait) {
            func.apply(context, args);
            previous = now;
        }
    }
}
设置定时器

当触发事件的时候,我们设置一个定时器,再触发事件的时候,如果定时器存在,就不执行,直到定时器执行,然后执行函数,清空定时器,这样就可以设置下个定时器。

// 第二版
function throttle(func, wait) {
    var timeout;
    var previous = 0;

    return function() {
        context = this;
        args = arguments;
        if (!timeout) {
            timeout = setTimeout(function(){
                timeout = null;
                func.apply(context, args)
            }, wait)
        }

    }
}

所以比较两个方法:
第一种事件会立刻执行,第二种事件会在 n 秒后第一次执行
第一种事件停止触发后没有办法再执行事件,第二种事件停止触发后依然会再执行一次事件


来源:博客

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 在进行窗口的resize、scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负...
    iqing2012阅读 881评论 0 1
  • 在上周的开发中,又遇到点击保存多次请求数据重复的问题,所以下来学习了一下js的防抖和节流。通过学习了解到,在进行窗...
    any_5637阅读 427评论 0 2
  • 参考博客:JS防抖和节流,感谢作者的用心分享日常开发过程中,滚动事件做复杂计算频繁调用回调函数很可能会造成页面的卡...
    上海_前端_求内推阅读 520评论 0 4
  • 一、什么是防抖和节流 Ps: 比如搜索框,用户在输入的时候使用change事件去调用搜索,如果用户每一次输入都去搜...
    拾柒_aab0阅读 309评论 0 1
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,747评论 16 22

友情链接更多精彩内容