防抖节流

117 阅读1分钟

防抖

概念

若事件被频繁触发,防抖能保证只有最后一次触发生效,前面N多次的触发都会被忽略(也就是持续触发不执行,不触发一段时间后才执行,若在一段时间内频发触发,当前时间被清除,重新计时)

使用场景:

  1. 搜索框输入查询;
  2. 表单验证;
  3. 按钮提交事件;
  4. scroll事件滚动触发;
  5. 浏览器窗口缩放,resize事件

代码

效果图

image.png

index.html

<body>
   <div class="box">
      <!-- 搜索框和按钮 -->
    <div class="search-box">
      <input type="text" id="ipt" placeholder="请输入要搜索的内容" />
      <button class="btnSearch">搜索</button>
     </div>
      <!-- 搜索建议 -->
      <div id="suggest-list"></div>
    </div>
    <!-- 模板引擎 -->
    <script type="text/html" id="tpl-suggestList">
      {{each result}}
      <div class="suggest-item">{{$value[0]}}</div>
      {{/each}}
    </script>
    <script src="./jquery.js"></script>
    <script src="./template-web.js"></script>
    <script src="./index.js"></script>
  </body>

index.css

 
      #ipt {
        width: 300px;
        height: 20px;
        outline: 0;
      }
      #suggest-list {
        width: 300px;
        display: none;
        border: 1px solid #ccc;
        padding-left: 5px;
      }
      .suggest-item:hover {
        cursor: pointer;
        background-color: skyblue;
        color: red;
      }

index.js

$(function () {
  // 1防抖
  // 1.1 定义延时器id
  var timer = null
  // 2 缓存数据列表
  // 2.1 定义全局缓存对象
  var cachObj = {}
  // 1.2定义防抖函数
  function debounceSearch(kw) {
    timer = setTimeout(function () {
      getSuggestList(kw)
    }, 500)
  }
  $('#ipt').on('keyup', function () {
    // 1.4 清空timer
    clearTimeout(timer)
    var keywords = $(this).val().trim()
    // 用户未输入内容,返回
    if (keywords <= 0) {
      return $('#suggest-list').empty().hide()
    }
    // 2.3 如果缓存中有,从缓存里拿
    if(cachObj[keywords]){
      return renderSuggestList(cachObj[keywords])
    }
    // 1.3输入内容
    debounceSearch(keywords)
  })
  // 发起请求,搜索框输入内容时,获取搜索建议(即下拉框相对应的内容)
  function getSuggestList(kw) {
    $.ajax({
      url: 'http://127.0.0.1//sug?q=' + kw,
      dataType: 'jsonp',
      success: function (res) {
        console.log(res)
        renderSuggestList(res)
      },
    })
  }
  // 渲染ui结构
  function renderSuggestList(res) {
    if (res.result.length <= 0) {
      return $('#suggest-list').empty().hide()
    }
    var htmlStr = template('tpl-suggestList', res)
    $('#suggest-list').html(htmlStr).show()
    // 2.2将搜索的结果,添加到缓存对象中
    var k = $('#ipt').val().trim()
    cachObj[k] = res
  }
})

缓存数据

用户在输入框中输入两个内容,network发起两次请求,若删除一个内容,network会将未删除的内容再次重新发送一次请求,导致未删除内容重复发送,若很多资源出现同样情况造成服务器压力

注意:代码如上---->index.js中序号2所示

节流

概念

降低触发的频率,隔一段时间后才触发

使用场景

  1. DOM元素的拖拽功能实现
  2. 射击游戏类
  3. 计算鼠标移动的距离
  4. 监听scroll事件

代码

index.html

<img src="./images/fly.png" id="fly" alt="Image" />

index.css

 #fly {
        width: 500px;
        height: 280px;
        position: absolute;
        cursor: pointer;
      }

index.js

 <script>
      // 未设置节流阀情况
      // $(function () {
      //   // 获取图片元素
      //   var fly = $('#fly')
      //   // 监听文档的 mousemove 事件
      //   $(document).on('mousemove', function (e) {
      //     // 设置图片的位置
      //     //  console.log(e.pageX, e.pageY);鼠标一移动,位置跟随立马显示(很多次)
      //     $(fly).css('left', e.pageX + 'px').css('top', e.pageY + 'px')
      //   })
      // })


      // 设置节流阀
      $(function () {
        var fly = $('#fly')
      // 1.定义timer 节流阀
        var timer = null;
        $(document).on('mousemove', function (e) {
          if (timer) {
            return
          } // 3.判断节流阀是否为空,如果不为空,则证明距离上次执行间隔不足1秒
          timer = setTimeout(function () {
            $(fly).css('left', e.pageX + 'px').css('top', e.pageY + 'px')
              // 2.设置鼠标跟随效果后,清空 timer 节流阀,方便下次开启延时器
            timer = null ;
            // console.log(e.pageX, e.pageY);鼠标一移动,位置出现频率相对减少
          }, 1000)
        })
      })
    </script>

效果

未设置节流阀

image.png

 

 

已设置节流阀

image.png