文章目录

  • 前言
  • 1. 要实现的UI效果
  • 2. 实现步骤
    • 2.1 获取用户输入的搜索关键词
    • 2.2 建议搜索列表的函数封装
    • 2.3 渲染建议列表的UI结构
      • 2.3.1 定义搜索建议列表
      • 2.3.2 定义模板结构
      • 2.3.1 定义渲染模板结构的函数
    • 2.4 美化搜索建议列表
      • 2.4.1 建议列表框美化
    • 2.5 输入框的防抖
      • 2.5.1 什么是防抖
      • 2.5.2 防抖的应用场景
      • 2.5.3 实现输入框的防抖
        • 1)定义防抖延时器
        • 2)定义防抖函数
        • 3)实现防抖
    • 2.6 缓存搜索的建议列表
      • 2.6.1 定义全局缓存对象
      • 2.6.2 将搜索结果保存到缓存对象中
      • 2.6.3 优先从缓存对象中获取搜索建议
  • 3. 完整案例代码

前言

这里来实现一个淘宝搜索框输入时,下拉智能弹出选项的案例

1. 要实现的UI效果

2. 实现步骤

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

为了获取到用户每次按下键盘输入的内容,需要监听输入框的 keyup 事件。
并且给搜索输入框框起一个 idipt,示例代码如下:

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

keyup 事件,鼠标弹起时触发

2.2 建议搜索列表的函数封装

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

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

2.3 渲染建议列表的UI结构

2.3.1 定义搜索建议列表

在原HTML结构基础上,在搜索框的下方添加一个div盒子,取id名为“suggest-list”,如下所示:

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

2.3.2 定义模板结构

因为接下来要渲染搜索建议列表,在渲染数据结构期间,我们最好使用模板引擎,因此必须要定义一个模板结构。

A、导入模板引擎

<script src="./lib/template-web.js"></script>

注:
本案例采用 art-template模板引擎
官方文档:http://aui.github.io/art-template/zh-cn/docs/index.html
art-template 模板引擎详细学习笔记:https://blog.csdn.net/zglibk/article/details/108048255

B、定义模板结构
分析:
由上面2.2 的代码"获取用户搜索建议列表" console.log(res)打印在控制台的信息可以看到一个从服务器返回的result对象,在这个对象中有一个result数组,每循环一次可以拿到一个建议项,里面每一个建议项又是一个数组,而实际上需要拿到的真正的建议内容是索引(下标)为0的这一项。

——因此,我们只需要循环result这个数组,就能拿到每一个搜索键,由于每一个键都可以用{{$ value}}来表示,则{{$ value}}里索引为0这一项,即为我们要获取的 搜索建议内容。

代码实现:
在模板引擎标签中,用{{each}} {{/each}}语法来循环result,每循环一次,就创建一个div标签(放搜索建议项),给div指定一个类名suggest-item,每循环一次就将 搜索建议内容 打印出来:

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

2.3.1 定义渲染模板结构的函数

封装自定义函数renderSuggestList,调用函数渲染模板结构。

 // 渲染UI结构
// 传入一个res参数(res就是待渲染的数据)
function renderSuggestList(res) {// 判断是否有待渲染的数据,如果没有就return出去,清空列表并隐藏if (res.result.length <= 0) {return $('#suggest-list').empty().hide();}// 调用模板引擎的template函数var htmlstr = template('tpl-suggestList', res) // 返回一个渲染好的html结构// 将渲染好的字符串放到搜索建议列表div中,并展示出来$('#suggest-list').html(htmlstr).show();
}

2.4 美化搜索建议列表

2.4.1 建议列表框美化

1)添加边框效果

#suggest-list {border: 1px solid #ccc;/* 默认隐藏 */display: none;
}


2)列表项美化

 /*设置行高、左边距*/
.suggest-item {line-height: 14px;padding: 8px;
}/*设置光标小手,列表项鼠标经过背景变色效果*/
.suggest-item:hover {cursor: pointer;background-color: #eee;
}

2.5 输入框的防抖

2.5.1 什么是防抖

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

实现方式: 每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法;
缺  点: 如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟。

函数防抖: 将多次操作合并为一次操作进行。原理是维持一个计时器,规定在延迟时间后触发函数,但是在延迟时间内再次触发的话,就会取消之前的计时器而重新设置。这样,就可以保证只有最后一次操作被触发。

其原理图示如下:

2.5.2 防抖的应用场景

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

如果没有防抖策略,那么每摁一下键盘,就会触发一次网络请求(如上图)。

注:输入框防抖,是最典型的应用场景

2.5.3 实现输入框的防抖

实现的步骤:

  1. 定义防抖的timer
  2. 定义防抖的函数;
  3. 在触发keyup事件时,立即清空timer

代码实现的基本结构:

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)
})

1)定义防抖延时器

var timer=null;

2)定义防抖函数

// 定义防抖的函数,延时500毫秒后,再请求数据接口
function debounceSearch(kw){// 开启延时器timer = setTimeout(function(){getSuggestList(kw);
,500)}

3)实现防抖

首先,在触发keyup事件的时候,就要立即清空timer:

$('#ipt').on('keyup', function() {clearTimeout(timer);//( ......略 )
}

然后,在获取搜索建议列表函数这块,就不能直接调用getsuggestList函数,要将keyup事件函数调用做一下修改:

 // 绑定用户输入框keyup事件$('#ipt').on('keyup', function() {// 清空timerclearTimeout(timer);var keywords = $(this).val().trim();if (keywords.length <= 0) {// 如果用户没有输入内容,则退出并清空隐藏列表return $('#suggest-list').empty().hide()}// getSuggestList(keywords); // 改为:debounceSearch(keywords);
})


这样,前面4次摁键(appl)的请求被取消,就只有最后1次(apple)才发起请求,实现了防抖

2.6 缓存搜索的建议列表

作用: 如果发起相同的请求,可以根据之前的缓存直接拿到搜索建议,就不用再重复发起请求,节约资源,提高搜索效率。

2.6.1 定义全局缓存对象

// 定义全局缓存对象var cacheObj={};

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

function renderSuggestList(res) {//... 略去无关代码// 1、获取到用户输入的内容,当做键var k = $('#ipt').val().trim();// 2、将数据做为值缓存到全局对象中cacheObj[k] = res;
}

2.6.3 优先从缓存对象中获取搜索建议

代码结构如下:

// 监听文本框的 keyup 事件$('#ipt').on('keyup', function() {// ...省略其他代码// 优先从缓存中获取搜索建议if (cacheObj[keywords]) {return renderSuggestList(cacheObj[keywords])}// 获取搜索建议列表debounceSearch(keywords)})

3. 完整案例代码

<!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、定义防抖的延时器 timervar timer = null;// 定义全局缓存对象var cacheObj = {};// 定义防抖函数,延时500毫秒后,再请求数据接口function debounceSearch(kw) {// 开启延时器timer = setTimeout(function() {getSuggestList(kw);}, 500)}// 为输入框绑定Keyup事件$('#ipt').on('keyup', function() {// 清空timerclearTimeout(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,// 发起JSONP请求dataType: 'jsonp',success: function(res) {renderSuggestList(res);}})}// 渲染UI结构// 传入一个res参数(res就是待渲染的数据)function renderSuggestList(res) {// 判断是否有待渲染的数据,如果没有就return出去,清空列表并隐藏if (res.result.length <= 0) {return $('#suggest-list').empty().hide();}// 调用模板引擎的template函数var htmlstr = template('tpl-suggestList', res); // 返回一个渲染好的html结构// 将渲染好的字符串放到搜索建议列表div中,并展示出来$('#suggest-list').html(htmlstr).show();// 1、获取到用户输入的内容,当做键var k = $('#ipt').val().trim();// 2、将数据做为值缓存到全局对象中cacheObj[k] = res;}})</script>
</body></html>

至此,整个案例完成。

全套案例 源码 保存:

百度网盘:https://pan.baidu.com/s/1x9lVxBRxQplctihB1PRdnw    提取码:1w9a

前端_网页编程 跨域与JSONP- 淘宝搜索案例相关推荐

  1. 前端调用第三方接口跨域问题(淘宝)

    前端调用第三方接口跨域问题 百度了好久,大部分的文章都前篇一律的说jsonp跨域,要不就是说配置CROS.看到那种文章出处应该都是一家,心好累.首先来说淘宝目前的接口是不支持jsonp请求的,配置CR ...

  2. 前端_网页编程 Form表单与模板引擎(上)

    目录 一.form表单的基本使用 1. 什么是表单? 2. 表单的组成部分 3. < form>标签的基本属性 3.1 action 3.2 target 3.3 method 3.4 e ...

  3. 前端_网页编程 Form表单与模板引擎(下)

    目录 续上一篇 6. 模板引擎的实现原理 6.1 正则与字符串操作 6.1.1 基本语法 6.1.2 分组 6.1.3 字符串的replace函数 6.1.4 多次replace 6.1.5 使用wh ...

  4. 前端_网页编程 Form表单与模板引擎(中)

    目录 ... ... (续上篇) 四.模板引擎的基本概念 1.定义 2. 优点 五.art-template模板引擎 1.art-template模板引擎介绍 2. art-template的安装 3 ...

  5. 前端_网页编程 HTTP协议(进阶)

    文章目录 内容 1. HTTP协议简介 1.1 什么是通信 1.1.1 现实生活中的通信 1.1.2 互联网中的通信 1.2 什么是通信协议 1.2.1 现实生活中的通信协议 1.2.2 互联网中的通 ...

  6. 网页现现实理服务器没有响应,前端_网页编程 HTTP协议(进阶)

    文章目录 内容 1. HTTP协议简介 1.1 什么是通信 1.1.1 现实生活中的通信 1.1.2 互联网中的通信 1.2 什么是通信协议 1.2.1 现实生活中的通信协议 1.2.2 互联网中的通 ...

  7. 前端_网页编程 Ajax加强

    目录 内容 一.XMLHttpRequest的基本使用 1. 什么是XMLHttpRequest 2. 使用xhr发起GET请求 3. xhr对象的readyState属性 4. 使用xhr发起带参数 ...

  8. 前端_网页编程 WebAPI_01

    01 - Web API 1.1. Web API介绍 1.1.1 API的概念 API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目 ...

  9. 前端_网页编程 节流

    文章目录 前言 1.什么是节流 2.节流的应用场景 3 节流案例 - 鼠标跟随效果 3.1 渲染UI结构并美化样式 3.2 不使用节流实现鼠标跟随效果 3.3 节流阀的概念 3.4 使用节流阀实现鼠标 ...

最新文章

  1. 一举拿下高可用与分布式协调系统设计!
  2. 英伟达深度学习推理引擎TensorRT,现在开源了
  3. 如何脱颖而出?成为优秀的人
  4. C异常处理实现: setjmp和longjmp
  5. php ajax sucess 失败,Ajax请求发送成功但不进success的解决方法(图文教程)
  6. win7 VS2008 编译luabind-0.9.1 动态库 静态库
  7. Gradle多项目构建–类似父pom的结构
  8. Windows 7硬盘安装方法大全
  9. JMS学习四(ActiveMQ消息过滤)
  10. mac php7.0 yaf 安装,MAC MAMP PRO PHP YAF 安装
  11. 沟通技巧系列 - 积极和移情倾听
  12. [翻译] 编写高性能 .NET 代码--第二章 GC -- 配置选项
  13. Django账号绑定邮箱时发送链接
  14. C++socket编程(六):6.1 设置socket的阻塞和非阻塞
  15. C#属性(Attribute)用法实例解析
  16. 中兴新支点操作系统_中兴新支点操作系统v3.2.2 最新版
  17. html视频播放卡顿,网页看视频卡怎么解决
  18. 【akka】初识Akka 简单介绍
  19. mixup:beyond empirical risk minimization
  20. 洛谷 P3386 【模板】二分图匹配

热门文章

  1. Amr and Pins
  2. 小时候都想当科学家后来只有他做到了——对话阿里云MVP朱祺
  3. 混合云下割裂的Web安全管理挑战如何破?
  4. 手把手教你数据不足时如何做深度学习NLP
  5. AI开发者福音!阿里云推出国内首个基于英伟达NGC的GPU优化容器
  6. 数字基础设施开源操作系统欧拉全新发布
  7. AI 如何推动双碳目标达成?施耐德电气这么说
  8. 快报:Java跌惨!Python背后或有推手?网友:心态已崩!
  9. Spark+Alluxio性能调优十大技巧
  10. 什么是oracle命名,ORACLE数据库命名规范