淘宝案例、防抖和节流

发布于:2022-12-29 ⋅ 阅读:(287) ⋅ 点赞:(0)

目录

3. 案例 – 淘宝搜索

3.1 要实现的UI效果 

3.2 获取用户输入的搜索关键词

3.3 封装getSuggestList函数

3.4 渲染建议列表的UI结构

1. 定义搜索建议列表

2. 定义模板结构

3. 定义渲染模板结构的函数

4. 搜索关键词为空时隐藏搜索建议列表

3.5 输入框的防抖

1. 什么是防抖

2. 防抖的应用场景

3. 实现输入框的防抖

3.6 缓存搜索的建议列表

1. 定义全局缓存对象

2. 将搜索结果保存到缓存对象中

3. 优先从缓存中获取搜索建议

4. 防抖和节流

4.1 什么是节流

4.2 节流的应用场景

4.3 节流案例 – 鼠标跟随效果 

1. 渲染UI结构并美化样式

2. 不使用节流时实现鼠标跟随效果

3. 节流阀的概念

4. 使用节流优化鼠标跟随效果 

4.4 总结防抖和节流的区别


3. 案例 – 淘宝搜索

3.1 要实现的UI效果

3.2 获取用户输入的搜索关键词

为了获取到用户每次按下键盘输入的内容,需要监听输入框的 keyup 事件,示例代码如下:

 // 监听文本框的 keyup 事件
 $('#ipt').on('keyup', function() {
   // 获取用户输入的内容
   var keywords = $(this).val().trim()
   // 判断用户输入的内容是否为空
   if (keywords.length <= 0) {
     return
   }
   // TODO:获取搜索建议列表
 })

3.3 封装getSuggestList函数

将获取搜索建议列表的代码,封装到 getSuggestList 函数中,示例代码如下:

 function getSuggestList(kw) {
   $.ajax({
      // 指定请求的 URL 地址,其中,q 是用户输入的关键字
      url: 'https://suggest.taobao.com/sug?q=' + kw,
      // 指定要发起的是 JSONP 请求
      dataType: 'jsonp',
      // 成功的回调函数
      success: function(res) { console.log(res) }
   })
 }

3.4 渲染建议列表的UI结构

1. 定义搜索建议列表

 <div class="box">
    <!-- tab 栏区域 -->
    <div class="tabs"></div>
    <!-- 搜索区域 -->
    <div class="search-box"></div>
    <!-- 搜索建议列表 -->
    <div id="suggest-list"></div>
 </div>

2. 定义模板结构

 <!-- 模板结构 -->
 <script type="text/html" id="tpl-suggestList">
    {{each result}}
       <div class="suggest-item">{{$value[0]}}</div>
    {{/each}}
 </script>

3. 定义渲染模板结构的函数

 // 渲染建议列表
 function renderSuggestList(res) {
    // 如果没有需要渲染的数据,则直接 return
    if (res.result.length <= 0) {
       return $('#suggest-list').empty().hide()
    }
    // 渲染模板结构
    var htmlStr = template('tpl-suggestList', res)
    $('#suggest-list').html(htmlStr).show()
 }

4. 搜索关键词为空时隐藏搜索建议列表

 $('#ipt').on('keyup', function() {
    // 获取用户输入的内容
    var keywords = $(this).val().trim()
    // 判断用户输入的内容是否为空
    if (keywords.length <= 0) {
       // 如果关键词为空,则清空后隐藏搜索建议列表
       return $('#suggest-list').empty().hide()
    }
    getSuggestList(keywords)
 })

3.5 输入框的防抖

1. 什么是防抖

防抖策略(debounce)是当事件被触发后,延迟 n 秒后再执行回调,如果在这 n 秒内事件又被触发,则重新计时。

2. 防抖的应用场景

用户在输入框中连续输入一串字符时,可以通过防抖策略,只在输入完后,才执行查询的请求,这样可以有效减少请求次数,节约请求资源;

3. 实现输入框的防抖

 var timer = null                    // 1. 防抖动的 timer

 function debounceSearch(keywords) { // 2. 定义防抖的函数
    timer = setTimeout(function() {
    // 发起 JSONP 请求
    getSuggestList(keywords)
    }, 500)
 }

 $('#ipt').on('keyup', function() {  // 3. 在触发 keyup 事件时,立即清空 timer
    clearTimeout(timer)
    // ...省略其他代码
    debounceSearch(keywords)
 })

3.6 缓存搜索的建议列表

1. 定义全局缓存对象

// 缓存对象
  var cacheObj = {}

2. 将搜索结果保存到缓存对象中

 // 渲染建议列表
 function renderSuggestList(res) {
    // ...省略其他代码
    // 将搜索的结果,添加到缓存对象中
    var k = $('#ipt').val().trim()
    cacheObj[k] = res
 }

3. 优先从缓存中获取搜索建议

 // 监听文本框的 keyup 事件
 $('#ipt').on('keyup', function() {
    // ...省略其他代码

    // 优先从缓存中获取搜索建议
    if (cacheObj[keywords]) {
       return renderSuggestList(cacheObj[keywords])
    }
    // 获取搜索建议列表
    debounceSearch(keywords)
  })
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>Document</title>
  <!-- 导入页面的基本样式 -->
  <link rel="stylesheet" href="./css/search.css" />
  <!-- 导入 jQuery -->
  <script src="./lib/jquery.js"></script>
  <!-- 导入模板引擎 -->
  <script src="./lib/template-web.js"></script>
</head>

<body>
  <div class="container">
    <!-- Logo -->
    <img src="./images/taobao_logo.png" alt="" class="logo" />

    <div class="box">
      <!-- tab 栏 -->
      <div class="tabs">
        <div class="tab-active">宝贝</div>
        <div>店铺</div>
      </div>
      <!-- 搜索区域(搜索框和搜索按钮) -->
      <div class="search-box">
        <input id="ipt" type="text" class="ipt" placeholder="请输入要搜索的内容" /><button class="btnSearch">
          搜索
        </button>
      </div>
      <!-- 搜索建议列表 -->
      <div id="suggest-list"></div>
    </div>
  </div>

  <!-- 模板结构 -->
  <script type="text/html" id="tpl-suggestList">
    {{each result}}
      <!--搜索建议项-->
      <div class="suggest-item">{{$value[0]}}</div>
    {{/each}}
  </script>

  <script>
    $(function () {
      // 1. 定义延时器的Id
      var timer = null
      // 定义全局缓存对象
      var cacheObj = {}

      // 2. 定义防抖的函数
      function debounceSearch(kw) {
        timer = setTimeout(function () {
          getSuggestList(kw)
        }, 500)
      }

      // 为输入框绑定 keyup 事件
      $('#ipt').on('keyup', function () {
        // 3. 清空 timer
        clearTimeout(timer)
        var keywords = $(this).val().trim()
        if (keywords.length <= 0) {
          return $('#suggest-list').empty().hide()
        }

        // 先判断缓存中是否有数据
        if (cacheObj[keywords]) {
          return renderSuggestList(cacheObj[keywords])
        }

        // TODO:获取搜索建议列表
        // console.log(keywords)
        // getSuggestList(keywords)
        debounceSearch(keywords)
      })

      function getSuggestList(kw) {
        $.ajax({
          url: 'https://suggest.taobao.com/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()

        // 1. 获取到用户输入的内容,当做键
        var k = $('#ipt').val().trim()
        // 2. 需要将数据作为值,进行缓存
        cacheObj[k] = res
      }
    })
  </script>
</body>

</html>

4. 防抖和节流

4.1 什么是节流

节流策略(throttle),顾名思义,可以减少一段时间内事件的触发频率。

4.2 节流的应用场景

  1. 鼠标连续不断地触发某事件(如点击),只在单位时间内只触发一次;
  2. 懒加载时要监听计算滚动条的位置,但不必每次滑动都触发,可以降低计算的频率,而不必去浪费 CPU 资源;

4.3 节流案例 – 鼠标跟随效果 

1. 渲染UI结构并美化样式

<!-- UI 结构 -->
<img src="./assets/angel.gif" alt="" id="angel" />

/* CSS 样式 */
html, body {
  margin: 0;
  padding: 0;
  overflow: hidden;
}#angel {
  position: absolute;
}

2. 不使用节流时实现鼠标跟随效果

$(function() {
   // 获取图片元素
   var angel = $('#angel')
   // 监听文档的 mousemove 事件
   $(document).on('mousemove', function(e) {      // 设置图片的位置
      $(angel).css('left', e.pageX + 'px').css('top', e.pageY + 'px')
   })
})

3. 节流阀的概念

高铁卫生间是否被占用,由红绿灯控制,红灯表示被占用,绿灯表示可使用。

假设每个人上卫生间都需要花费5分钟,则五分钟之内,被占用的卫生间无法被其他人使用。

上一个人使用完毕后,需要将红灯重置为绿灯,表示下一个人可以使用卫生间。

下一个人在上卫生间之前,需要先判断控制灯是否为绿色,来知晓能否上卫生间。

  • 节流阀为空,表示可以执行下次操作;不为空,表示不能执行下次操作。
  • 当前操作执行完,必须将节流阀重置为空,表示可以执行下次操作了。
  • 每次执行操作前,必须先判断节流阀是否为空。

4. 使用节流优化鼠标跟随效果 

$(function() {
  var angel = $('#angel')
  var timer = null // 1.预定义一个 timer 节流阀
  $(document).on('mousemove', function(e) {
    if (timer) { return } // 3.判断节流阀是否为空,如果不为空,则证明距离上次执行间隔不足16毫秒
    timer = setTimeout(function() {
      $(angel).css('left', e.pageX + 'px').css('top', e.pageY + 'px')
      timer = null // 2.当设置了鼠标跟随效果后,清空 timer 节流阀,方便下次开启延时器
    }, 16)
  })
})

4.4 总结防抖和节流的区别

  • 防抖:如果事件被频繁触发,防抖能保证只有最有一次触发生效!前面 N 多次的触发都会被忽略!
  • 节流:如果事件被频繁触发,节流能够减少事件触发的频率,因此,节流是有选择性地执行一部分事件!
本文含有隐藏内容,请 开通VIP 后查看