javaScript中的防抖

358 阅读1分钟

前言

本文讲解一下js中防抖思想,下方有实现防抖的基本代码,可以复制到自己的编辑器看看效果哦。也有实际的应用场景,会HTML、CSS、JQuery以及使用jQuery发送Ajax请求即可。


一、什么是防抖?

防抖阻止了事件的多次调用,规定时间内只会执行一次。

二、防抖解决了什么问题

假设一个用户高频点击一个按钮,点击按钮后会向后台发送请求,如果不使用防抖,就会发送许多重复的Ajax请求,造成服务器压力。使用防抖后,规定时间内,只会发送一次Ajax请求,可以有效地减缓服务器的压力。

三、实现防抖的基本代码

通过监听输入框的输入事件,通过定时器每隔一秒获取一次用户输入的内容,如果一秒内用户又进行了输入,清除上一次的定时器,重新计时一秒,计时结束后将用户输入的内容打印到控制台。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>debounce</title>
  </head>
  <body>
      <input type="text" placeholder="请输入您要搜索的内容~" />
    <script>
      let timer = null
      $('input').on('input',function(){
          console.log('没有防抖',$('input').val())
          // 向清除一次定时器
          clearTimeout(timer)
          // 重新开启一个定时器
          timer = setTimeout(() => {
              // 如果input输入框的值为空,就终止执行后面的代码
              if(!$('input').val()) return
              console.log('加了防抖后',$(this).val())
          }, 1000);
      })

      // $('input').on(
      //   'input',
      //   debounce(function () {
      //     if (!$(this).val()) return
      //     console.log($(this).val())
      //   })
      // )
      // // 封装代码,提高代码的复用性
      // function debounce(fn) {
      //   let timer = null
      //   return function () {
      //     clearTimeout(timer)
      //     timer = setTimeout(() => {
      //       // 这里的 this 指向 window
      //       // 通过 call() 方法改变this的指向
      //       fn.call(this)
      //     }, 1000)
      //   }
      // }
    </script>
  </body>
</html>

四、防抖的应用场景

想必大家平时都有逛购物网站的习惯,当我们在搜索框搜索某件商品时,只要输入关键字就会在搜索框下出现对应的联想列表。但是联想列表不是实时展示的,可以延迟500毫秒或者1秒,将用户输入的关键字通过Ajax请求提交给后台,当得到后台服务器响应后,再将联想列表展示给用户。这样的操作大大地减少了对服务器的请求压力,延迟适当的时间,也可以让用户有足够的时间将想要搜索的关键字写完整。

1.代码实现

代码如下(示例):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>防抖</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      div {
        width: 500px;
        margin: auto;
      }
      .box {
        margin-top: 200px;
        width: 500px;
        height: 35px;
        border: 1px solid #ccc;
        border-radius: 8px;
        overflow: hidden;
      }

      a {
        text-decoration: none;
        color: #fff;
        width: 60px;
        height: 100%;
        line-height: 35px;
        text-align: center;
        background-color: steelblue;
      }

      .fl {
        float: left;
      }

      .fr {
        float: right;
      }

      input {
        padding-left: 20px;
        width: 418px;
        height: 100%;
        border: 0;
        outline: none;
      }

      .list {
        display: none;
        width: 500px;
        border: 1px solid #ccc;
        border-top: none;
        border-radius: 8px;
      }

      li {
        list-style: none;
        padding-left: 30px;
        height: 30px;
        line-height: 30px;
        border-bottom: 1px solid #ccc;
      }

      li:last-child {
        border-bottom: none;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <input type="text" class="fl" placeholder="请输入您要搜索的内容~" />
      <a href="javascript:;" class="fr">搜索</a>
    </div>
    <div class="list">
      <ul></ul>
    </div>

    <script src="./jquery-3.5.1.min.js"></script>
    <script>
      let timer = null
      // 给input输入框绑定input事件
      $('input').on('input', function () {
        clearTimeout(timer)
        timer = setTimeout(() => {
          // 如果输入框的内容为空,就终止代码的执行
          if (!$(this).val()) return
          
          let kw = $(this).val()
          
          // 发送Ajax请求
          $.ajax({
            type: 'GET',
            url: 'http://www.liulongbin.top:8000/v1_0/suggestion?q=' + kw,
            success: function (res) {
              // 判断服务器返回的结果,如果没有内容弹框提示并终止后续代码执行
              if (res.data.options.length === 0) {
                alert('暂时没有搜索结果~')
                $('input').val('')
                return
              }
              // 遍历服务器返回的数据
              res.data.options.forEach(item => {
                // 将每一项追加到ul列表中
                $('.list ul').append(`<li>${item}</li>`)
              })
              // 展示联想列表
              $('.list').show()
            }
          })
        }, 1000)
        // 隐藏联想列表展示并清空ul内的内容
        $('.list').hide().find('ul').empty()
      })
    </script>
  </body>
</html>

2.结果展示

在这里插入图片描述


总结

本来想给大家做一个GIF动图展示的,但是没有找到软件,感兴趣的小伙伴可以复制代码到自己的编辑器运行看下效果。如果觉得对你有帮助的话,辛苦点赞支持一下~三克油