一个小需求带你了解防抖和节流

335 阅读2分钟

一个小需求带你了解防抖和节流

这是我参与8月更文挑战的第1天,活动详情查看: 8月更文挑战

总结最近碰到的一个有关防抖节流相关的需求,将笔记整理跟大家分享,这个知识经常在前端面试的时候会问到,所以做个记录,希望对大家有所帮助,如果有什么问题,可以指出,会积极修正。
如果大家喜欢,可以点赞或留言~~~~,谢谢大家~~~

> 需求场景:需要做一个底部的button,在页面滚动的时候底部按钮向下收起,停止滚动的时候向上弹出,收起和弹出添加动画效果

247498b9fb492669a04c45771.gif 思考:控制面板收起弹出的事件绑定比较简单,可以直接绑定到window.onscroll事件上,通过bottom的值可以控制面板的收起和弹出,初步的设想是这样

<!DOCTYPE html>
  <head></head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .title {
      font-size: 36px;
      margin: 20px;
    }
    .child {
      height: 1000px;
      margin: 20px;
      background-color: aqua;
    }
    #detail-btn {
      position: fixed;
      z-index: 999;
      bottom: 0;
      width: 100%;
      height: 100px;
      background-color: blueviolet;
    }
  </style>
  <body>
    <div class="div-wrapper">
      <div class="title">防抖节流的应用</div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
    <div id="detail-btn"></div>
  </body>
  <script>
    let dom = document.getElementById('detail-btn');
    window.onscroll = function() {
      dom.style.bottom = '-100px';
      setTimeout(() => {
        fn();
      }, 1000)
    }
    function fn() {
      dom.style.bottom = '0px';
    }
  </script>
</html>

运行一下上面的代码我们可以发现,不添加动画的情况下底部按钮会有闪现的情况,且如果页面滚动操作很频繁会造成面板闪来闪去,这是因为每个setTimeout任务都被执行了,所以这个时候面试官可能就会考察你对防抖节流的理解

防抖就和这个面板弹出的情况是一致的,如果有1000ms持续没有触发页面滚动事件那么面板才会弹起,否则每次点击都重新计时,那么我们就可以优化一下加入防抖

<!DOCTYPE html>
  <head></head>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    .title {
      font-size: 36px;
      margin: 20px;
    }
    .child {
      height: 1000px;
      margin: 20px;
      background-color: aqua;
    }
    #detail-btn {
      position: fixed;
      z-index: 999;
      bottom: 0;
      width: 100%;
      height: 100px;
      background-color: blueviolet;
      transition: bottom .3s ease-in;
    }
  </style>
  <body>
    <div class="div-wrapper">
      <div class="title">防抖节流的应用</div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
    </div>
    <div id="detail-btn"></div>
  </body>
  <script>
    let dom = document.getElementById('detail-btn');
    window.onscroll = function() {
      dom.style.bottom = '-100px';
      throttle(fn, 1000)();
    }
    function fn() {
      dom.style.bottom = '0px';
    }
    function throttle(fn, wait) {
      let timer = null;
      return function () {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(() => {
          fn.call(this, arguments);
        }, wait)
      }
    }
  </script>
</html>

很多场景题和我们的知识点都息息相关,平时我们可以多做一些尝试,先不看作者的解释直接拿原生先实现,明白了原理,不管是vue还是react的框架,想要实现这个功能都是轻车熟路,比如我们使用的是vue的框架的话,那么我们的fn就是在控制v-if或者v-show中的变量的值