防抖和节流

防抖 debounce

函数防抖就是在函数需要频繁触发的情况下,只有足够的空闲时间,才执行一次。

防抖的原理:你尽管触发事件,但是我一定在事件触发的n秒后才执行,如果你在触发事件n秒内又触发了这个事件,那我就以新事件的时间为准,n秒后在执行

典型应用

  • 百度搜索框在输入稍有停顿时才更新推荐热词。
// 频繁触发时,清楚对应的定时器,然后再开一个定时器,delay秒后执行
function debounce(handler, delay) {

    delay = delay || 300;
    var timer = null;

    return function () {
        // 保留调用时的this上下文
        var _self = this,
            // 保留调用时传入的参数
            _args = arguments;
        // 每次事件触发时 都去清除之前的旧定时器
        if(timer){
            clearTimeout(timer);
        } 
        // 设定新定时器
        timer = setTimeout(function () {
            handler.apply(_self, _args);
        }, delay);
    }
}

实例

// 不希望被频繁调用的函数
function add(counterName) {
    console.log(counterName + ":  " + this.index++);
}

// 需要的上下文对象
let counter = {
    index: 0
}

// 防抖的自增函数,绑定上下文对象counter
let db_add = debounce(add, 10).bind(counter)

// 每隔500ms频繁调用3次自增函数,但因为防抖的存在,这3次内只调用一次
// setInterval(function () {
//     db_add("someCounter1");
//     db_add("someCounter2");
//     db_add("someCounter3");
// }, 500)


/**
        * 预期效果:
        *
        * 每隔500ms,输出一个自增的数
        * 即打印:
          someCounter3:  0
          someCounter3:  1
          someCounter3:  2
          someCounter3:  3
        */

节流 throttle

一个函数只有在大于执行周期时才执行,周期内调用不执行。好像水滴积攒到一定程度才会触发一次下落一样。

典型应用:

节流原理:如果你持续触发事件,每隔一段时间,只会执行一次事件

  • 鼠标移动事件
  • 窗口调整
  • 页面滚动
function throttle(handler, wait) {
    wait = wait || 300;
    var lastTime = 0;   // 上一次触发回调的时间
    return function () {
        // 保留调用时的this上下文
        var _self = this,
            // 保留调用时传入的参数
            _args = arguments;
        // 记录本次触发回调的时间
        var nowTime = new Date().getTime();
        if ((nowTime - lastTime) > wait) {
            // 如果时间间隔大于设定的时间间隔阈值 则执行回调
            handler.apply(_self, _args);
            lastTime = nowTime;
        }
    }
}

使用节流后 在盒子内移动 每300毫秒打印一次结果

let handleMouseMove = throttle(function(e){
    console.log(e.pageX,e.pageY);
})
// 使用节流后 在盒子内移动 每300毫秒打印一次结果
document.querySelector(".box").addEventListener("mousemove",handleMouseMove)

在这里插入图片描述

复杂但好用版:

function throttle(fn, interval, context, firstTime) {
  let timer;
  firstTime = typeof firstTime !== 'undefined' ? firstTime : true;
  return function() {
    let args = arguments;
    let __me = this;
    if (typeof context !== 'undefined') {
      __me = context;
    }

    if (firstTime) {
      fn.apply(__me, args);
      return (firstTime = false);
    }

    if (timer) {
      return false;
    }

    timer = setTimeout(function() {
      clearTimeout(timer);
      timer = null;

      fn.apply(__me, args);
    }, interval);
  };
}

节流与防抖的本质

以闭包的形式存在,通过对事件对应的回调函数进行包裹、以自由变量的形式缓存时间信息,最后用定时器时间差来控制事件的触发频率。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值