防抖及其实现思路

211 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

防抖较节流比较复杂,还是拿MOBA游戏举例.如果你在回城中使用了技能或者被攻击了就需要重新读条回城(当然我们不考虑插眼这一特殊情况).下面还是用代码举例

 <div class="box"></div>
<script>
    let i = 1
    const box = document.querySelector('.box')
    //防抖
    box.addEventListener('mousemove',function(){
       box.innerHTML = ++i;
    })
    </script>

如js代码所示,页面中创建一个div鼠标在里面每次移动一次i的值就加1.相当与点击了回城马上就到了泉水,而防抖的意义就是加一个读条过程.当我的页面收到移动效果i准备加一,而这时你又移动了一次,那么我取消这次加一重新开始准备加一,而这时你又移动了一次......多次触发,规定时间之内,取消掉之前的操作,如你一直在我规定时间之内移动那么我永远的不会执行.思路明了,下面开始实现

<script>
    // 需求1: 点击box(鼠标移动触发频率更高),就触发修改div内容的逻辑;
    let box = document.querySelector('.box');
    let i = 0;
    function setNum() {
      box.innerHTML = ++i;
    }
    // 1. 普通 - 绑定事件
    // box.addEventListener('mousemove', setNum);
    // 2. 防抖 - 自己封装实现
    box.addEventListener('mousemove', debounce(setNum, 1000));
    // 封装一个方法  _.debounce(setNum, 1000)
    // 通过打印,验证返回值是一个函数
    // console.log(_.debounce(setNum, 1000)); 
    //   两个参数: 函数和时间;   一个返回值: 事件对应的函数;
    function debounce(fn, time) {
      // return的外面定义一个变量,赋值为定时器的id值;
      let timerID;  // 一定要用 let 定义,不能用const
      return function () {
        // 每次触发都清除上一次的操作;
        clearTimeout(timerID);
        // 多次触发,规定时间之内,取消掉之前的操作;  (延时器)
        // 此处的 timerID 前面不能带有 let
        timerID = setTimeout(function () {
          // 延迟 time 时间,执行 fn(); 
          fn();
        }, time);
      }
    }
  </script>

每次触发都清除上一次的操作

防抖函数的应用场景:

1.输入框或搜素框中频繁的输入内容或者提交信息;

2.频繁的点击按钮,触发某个事件