前端_网页编程 跨域与JSONP- 淘宝搜索案例
文章目录
- 前言
- 要实现的UI效果
- 实现步骤
- 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 优先从缓存对象中获取搜索建议
- 完整案例代码
前言
这里来实现一个淘宝搜索框输入时,下拉智能弹出选项的案例
1. 要实现的UI效果
2. 实现步骤
2.1 获取用户输入的搜索关键词
为了获取到用户每次按下键盘输入的内容,需要监听输入框的 keyup 事件。
并且给搜索输入框框起一个 id
为 ipt
,示例代码如下:
// 监听文本框的 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 实现输入框的防抖
实现的步骤:
- 定义防抖的
timer
; - 定义防抖的函数;
- 在触发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() {
// 清空timer
clearTimeout(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、定义防抖的延时器 timer var timer = null; // 定义全局缓存对象 var cacheObj = { }; // 定义防抖函数,延时500毫秒后,再请求数据接口 function debounceSearch(kw) { // 开启延时器 timer = setTimeout(function() { getSuggestList(kw); }, 500) } // 为输入框绑定Keyup事件 $('#ipt').on('keyup', function() { // 清空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, // 发起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
还没有评论,来说两句吧...