通过这个案例,我们了解一些知识,比如模版引擎、防抖和节流
先来看看效果图:
功能:当用户输入关键字后,对应的数组建议罗列出来
先来看看html框架
宝贝店铺
首先为输入框绑定keyup事件
获取用户输入的内容 $(this).val().trim(),对文本框里面的内容进行判断,如果文本框里面没有内容 就把建议列表清空并隐藏
$('#ipt').on('keyup', function () { var keywords = $(this).val().trim() if (keywords.length <= 0) { return $('#suggest-list').empty().hide() } getSuggestList(keywords) })
接下来封装一个getSuggestList函数,发送一个JSONP请求,获取到对应的建议列表 有个q属性 kw就是我们输入的关键字
function getSuggestList(kw) { $.ajax({ url: 'https://suggest.taobao.com/sug?q=' + kw, dataType: 'jsonp', success: function (res) { console.log(res) } }) }
将每一条建议渲染到页面中【定义模版结构】在定义模版引擎前,先给大家介绍哈什么是模版引擎
概念:模版引擎,顾名思义,它可以根据程序员指定的模版结构和数据,自动生成一个完整的html页面
执行过程:程序员提供数据和模版结构传给模版引擎 模版引擎在内部将两者做成一个完成的html结构
好处:
在本案例中,我使用的模版引擎是art-template
使用步骤:
- 导入 art-template
- 定义数据
- 定义模版
- 调用template函数【有两个参数 数据和模版】
- 渲染html结构
art-template标准语法
art-template提供{ {}}这种语法格式,在{ {}}内可以进行变量输出,或循环数组等操作,这种{ {}}语法在art-template中被称为标准语法
- 标准语法-输出
在{ {}}语法中,可以进行变量的输出、对象属性的输出、三元表达式输出、逻辑或输出、加减乘除等表达式输出
比如---------{ {value}} || { {obj.key}} || { {obj['key']}} || { {a?b:c}} || { {a || b}} || { {a+b}}
- 标准语法-原文输出
语法:{ { @value}}
如果要输出的value值中,包含了html标签结构,则需要使用原文输出语法,才能保证html标签被正常渲染
- 标准语法-条件输出
如果要实现条件输出,则可以在{ {}}中使用if...else if .../if的方式,进行按需输出
{ {if value}} 按需输出内容 { {/if}}
{if v1}} 按需输出的内容 { {else if v2}} 按需输出的内容{ {/if}}
- 标准语法-循环输出
语法:
{ {each arr}}
{ {$index}} { {$value}}
{ {/each}}如果要实现循环输出,则可以在{ {}} 内,通过each语法循环数组,当前循环的索引使用$index进行访问
- 标准语法-过滤函数
{ {value} | filterName}} 左边是一个值,右边是一个处理函数,返回一个新值 相当于调用过滤器函数
定义过滤器的基本语法:
template.defaults.imports.filterName = function(value){ return处理的结果 }
再回到案例当中,现在需要实现将建议内容渲染到页面中
使用模版引擎里面的循环输出,去循环result里面的每一项,没循环一次就创建一个div,数据是 { {$value[0]}} 每一个数组键的第一个值
//模版结构 循环服务器返回的数据 去循环result里面的每一项,
定义渲染模版结构的函数
先判断里面有没有要渲染的数据,没有的话讲建议列表 清空并隐藏,
如果有
var htmlStr = template('tpl-suggestList', res) 调用模版引擎函数
$('#suggest-list').html(htmlStr).show() 将处理好的数据渲染到建议列表,并将此显示// 渲染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() }
细节问题一:当用户输入内容的时候,每输入一个字母,就会服务器就会请求一次数据,请求的次数很多
解决方案:通过防抖,有效减少请求的次数,节约请求资源
实现输出框的防抖
var timer = null //1、防抖动的timer
function debounceSearch(keywords) { //2、定义防抖的函数
timer = setTimerout(function() {
// 发起JSONP请求
getSuggestList(keywords)
},500)
$("#ipt").on('keyup',function(){ // 3、在触发keyup事件时,立即清空timer
clearTimeout(timer)
....
debounceSearch(keywords)
)
在500毫秒以内,清除定时器 ,服务器就不会发起请求
细节问题二:当我们输入 apple 后 在输入一个mac,如果我们值保留appla的搜索的时候,服务器又会重新请求一次。 重复请求了
解决方案:将我们之前的搜索建议进行缓存,再发起相同的请求的时候,就去寻找缓存里面的建议,提高了搜索效率
// 定义全局缓存对象 var cacheObj = {} // 1. 获取到用户输入的内容,当做键 var k = $('#ipt').val().trim() // 2. 需要将数据作为值,进行缓存 cacheObj[k] = res
优先从缓存中取数据,在发起请求之前,先判断缓存里有没有这个键
在keyup事件后面进行一次判断
//先判断缓存中是否有数据 if (cacheObj[keywords]) { return renderSuggestList(cacheObj[keywords]) } debounceSearch(keywords)
js完整代码