美文网首页
JS中连续触发事件稀释方法 -- 函数节流、函数防抖

JS中连续触发事件稀释方法 -- 函数节流、函数防抖

作者: 辣瓜瓜 | 来源:发表于2018-03-20 19:38 被阅读189次

概念解释

在一定时间内,代码执行的次数不一定要非常多,执行的代码越多,带来的效果也是一样,反而会因为执行次数过多而带来性能的损耗。这时可以把js代码的执行次数控制一定范围内范围。这样既能节省浏览器CPU资源损耗,又能让页面浏览更加流畅,不会因为js的执行而发生卡顿或产生额外的请求。
函数节流、函数防抖都是优化高频率执行js代码的一种手段。

适用情景

  1. window对象的resize、scroll事件
  2. 拖拽时的mousemove事件
  3. 射击游戏中的mousedown、keydown事件
  4. 文字输入、自动完成的keyup事件

实际上,对于window的resize事件,需求大多为停止改变大小n毫秒后,执行后续处理,即函数防抖;
而其他事件大多需求是以一定的频率执行后续处理,即函数节流。

函数防抖 debounce

函数防抖,即延迟一段时间再执行函数,如果这段时间内又触发了该函数,则清除已累计时间,重新计算延迟时间。只有在一段时间内一直没有触发函数,才能继续触发。
比如:生活中的坐公交,就是一定时间内,如果有人陆续刷卡上车,司机就不会开车。只有别人没刷卡了,司机才开车。
再如:代码中使用onresize事件处理程序时,当调整浏览器大小的时候,该事件会连续触发,使用函数防抖延迟一段时间再执行函数,如果这段时间内继续调整浏览器大小,则重新计算延迟时间,解决短时间内重复调用事件的这个问题。

基本原理

第1次触发函数,清除前一次的定时器,创建一个定时器,在指定的时间间隔之后运行代码。当第二次触发该函数时,如果前一个定时器已经执行过了,这个操作就没有任何意义。如果前一个定时器尚未执行,就将其替换为一个新的定时器重新计算时间。目的是达到只有在上一次执行函数的请求停止了一段时间之后出发的函数才可以执行。

实现

/**
* 返回函数连续调用时,停留时间大于或等于 idle,action 才会执行
* @param idle   {number}    停留空闲时间,单位毫秒
* @param action {function}  请求关联函数,实际应用需要调用的函数
* @return {function}    返回客户调用函数
*/ 
var debounce = function(idle, action){ 
  var last; 
  return function(){ 
    var ctx = this, 
        args = arguments; 
    clearTimeout(last); 
    last = setTimeout(function(){ 
        action.apply(ctx, args);// 延迟idle毫秒后 执行action 
    }, idle); 
  }; 
}; 

使用

function demo() {
    console.log("函数防抖");
}
window.onresize = debounce(3000, demo);

函数节流 throttle

指在一定时间内JS方法只运行一次,间隔一个执行周期后才能再触发,避免某些函数触发频率过高,占用不必要的请求占用资源开销。
比如:
1.滚动条滚动到底部时触发的函数,触发一次即可,避免多次请求;
2.避免用户短时间内按钮重复点击提交。

原理

函数节流与函数防抖不同的是,函数节流间隔的执行周期每次都是固定的,而函数防抖每次间隔的执行周期是不固定的。

  1. 第一次触发函数时flag = true,并没有在执行周期中,函数可以正常向下执行,修改flag为false;
  2. 在1秒的执行周期内,再次触发函数,此时flag = false,不能继续触发,则返回;
  3. 在1秒内无论执行多少次,flag 始终为false,不继续向下执行;
  4. 1秒后,修改为flag = true;
  5. 此时若触发函数,回到第1步判断。
实现
/**
 * 频率控制 返回函数连续调用时,action 执行频率限定为 次 / delay
 * @param delay  {number}    延迟时间,单位毫秒
 * @param action {function}  请求关联函数,实际应用需要调用的函数
 * @return {function}    返回客户调用函数
 */
var throttle = function(delay, action) {
    var last = 0;
    return function() {
        var curr = +new Date()
        if (curr - last > delay) {
            action.apply(this, arguments);
            last = curr;
        }
    }
}

//使用定时器方式的简单实现
var flag = true;
window.onresize = function(){
    if(!flag){
       return;// 判断是否在执行中,如果是则直接return
    }
    flag = false;
    setTimeout(function(){
        flag = true;
        //触发函数
    }, 1000);
};

使用

function demo() {
    console.log("函数节流");
}
window.onresize = throttle(3000, demo);


资料参考:

http://blog.csdn.net/hj7jay/article/details/54943606

https://zhuanlan.zhihu.com/p/28753959






相关文章

  • JS中连续触发事件稀释方法 -- 函数节流、函数防抖

    概念解释 在一定时间内,代码执行的次数不一定要非常多,执行的代码越多,带来的效果也是一样,反而会因为执行次数过多而...

  • JavaScript防抖和节流

    无论是防抖还是节流都是为了避免回调函数中的处理随着连续触发事件每次都执行 防抖和节流都是为了防止函数(事件)的连续...

  • 面试过程中遇到的问题记录

    1.js的防抖和节流 函数防抖 函数防抖原理(debounce):当持续触发事件时,一定时间段内没有再触发事件,事...

  • js 函数节流和防抖

    js 函数节流和防抖 throttle 节流 应用场景 触发mousemove事件的时候, 如鼠标移动。 触发ke...

  • 防抖与节流

    防抖:事件持续触发,但只有当事件停止触发后n秒才执行函数。 节流:事件持续触发时,每n秒执行一次函数。 防抖 节流

  • JS 节流和防抖

    1. 概念介绍 debounce: 防抖函数,高频事件触发 在 n 秒内只会执行一次,节流会稀释函数的执行频率; ...

  • 什么是防抖和节流?哪里会用到?重点是什么?怎样实现源码?

    什么是防抖和节流? 函数的防抖和节流,都是优化高频率执行js代码的方法,具体来说:函数防抖:是在频繁触发的情况下,...

  • js中什么是防抖节流?

    防抖在连续触发的事件中,将多次执行的事件处理函数变为最后只执行一次。 Code 节流在连续触发的事件中,将多次执行...

  • js节流和防抖

    js节流和防抖 1、概念 节流函数是指一定时间内方法只执行一次。防抖函数是指一定时间内,事件被频繁触发,但只执行一...

  • JS函数防抖

    JS 中的函数防抖 一、什么是函数防抖? 概念: 函数防抖(debounce), 就是指触发事件后,在 n 秒内函...

网友评论

      本文标题:JS中连续触发事件稀释方法 -- 函数节流、函数防抖

      本文链接:https://www.haomeiwen.com/subject/nhnzfftx.html