学习一下 常说的防抖

start

  • 总是听到防抖节流,但是一直没有分清楚这两者之间的区别。
  • 现在开始学习也不晚,先学习一下防抖

概念

防抖(debounce),防止抖动, 短时间内触发多次,最终只触发一次;

实现防抖

例如我有一个输入框,我希望在我键盘停止输入的 500 毫秒之后,可以自动搜索。

<!DOCTYPE html>
<html lang="en">
  <body>
    <input type="text" id="in" />

    <script>
      var input = document.querySelector('#in')

      let say = function (e) {
        console.log('值改变事件', e.target.value)
      }

      input.addEventListener('keyup', say)
    </script>
  </body>
</html>

在这里插入图片描述

可以看到在我上面的截图中,我本意是想搜索你好,但是我的 say 方法,在操作键盘的时候被执行了很多次。(但是我本意只是想,在我停止操作后,执行一次 输出你好)这种时候就可以利用防抖这个概念了。

再重温一下,防抖:短时间内触发多次,最终只触发一次; (当我操作键盘,如果 500 毫秒之内多次触发键盘,及重新计时)

<!DOCTYPE html>
<html lang="en">
  <body>
    <input type="text" id="in" />

    <script>
      var input = document.querySelector('#in')

      var say = function (e) {
        console.log('值改变事件', e.target.value)
      }

      input.addEventListener('keyup', debounce(say, 500))

      function debounce(fn, wait) {
        // 1.记录定时器
        var timer
        console.log(timer, '111')

        // 2.它本身需要返回一个方法
        return function () {
          // 3.清除之前的定时器(这个地方 debounce 只执行一次,然后由于闭包,常驻于内存,所以会一直存储着定时器相关的信息。)
          clearTimeout(timer)
          var that = this
          var arr = arguments

          timer = setTimeout(function () {
            fn.apply(that, arr)
          }, wait)
        }
      }
    </script>
  </body>
</html>

如果想首次已进入就执行,间隔一段时间后才可以执行?

<!DOCTYPE html>
<html lang="en">
  <body>
    <input type="text" id="in" />

    <script>
      var input = document.querySelector('#in')

      var say = function (e) {
        console.log('值改变事件', e.target.value)
      }

      input.addEventListener('keydown', debounce(say, 500, { immediate: true }))

      function debounce(fn, wait, option) {
        var timer

        return function () {
          if (timer) {
            clearTimeout(timer)
          }

          var that = this
          var arr = arguments

          if (option && option.immediate) {
            var isRun = !timer
            timer = setTimeout(function () {
              console.log(timer)
              timer = null
            }, wait)

            if (isRun) fn.apply(that, arr)
          } else {
            timer = setTimeout(function () {
              fn.apply(that, arr)
            }, wait)
          }
        }
      }
    </script>
  </body>
</html>

个人总结:

  • 防抖:一段时间内不管你触发多少次,我只触发一次;
  • 举一个别人说的比较好的例子,防抖就类似于我们手机设置了10分钟息屏,当我们操作了手机,手机的息屏计时就重新计算,直到我们真的没有操作手机达到10分钟,手机才会真正息屏。
  • 手写的过程中遇到的问题:
    1. timer这个变量如何实现一直记录着前一个定时器返回值。debounce 只执行一次,timer由于闭包,常驻于内存;
    2. 切记要存储定时器的返回值;
    3. 首次进入执行这个逻辑,稍微有点绕。这个地方很巧妙,当!timer为 true , 才会执行真正的回调;简单总结一下就是:我首次进来就触发,必须等我这个定时器执行完毕,才可再次触发(定时器中的timer=null就是这个意思)。

在这里插入图片描述

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lazy_tomato

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值