前端_网页编程 跨域与JSONP- 淘宝搜索案例
文章目錄
- 前言
- 1. 要實(shí)現(xiàn)的UI效果
- 2. 實(shí)現(xiàn)步驟
- 2.1 獲取用戶輸入的搜索關(guān)鍵詞
- 2.2 建議搜索列表的函數(shù)封裝
- 2.3 渲染建議列表的UI結(jié)構(gòu)
- 2.3.1 定義搜索建議列表
- 2.3.2 定義模板結(jié)構(gòu)
- 2.3.1 定義渲染模板結(jié)構(gòu)的函數(shù)
- 2.4 美化搜索建議列表
- 2.4.1 建議列表框美化
- 2.5 輸入框的防抖
- 2.5.1 什么是防抖
- 2.5.2 防抖的應(yīng)用場景
- 2.5.3 實(shí)現(xiàn)輸入框的防抖
- 1)定義防抖延時器
- 2)定義防抖函數(shù)
- 3)實(shí)現(xiàn)防抖
- 2.6 緩存搜索的建議列表
- 2.6.1 定義全局緩存對象
- 2.6.2 將搜索結(jié)果保存到緩存對象中
- 2.6.3 優(yōu)先從緩存對象中獲取搜索建議
- 3. 完整案例代碼
前言
這里來實(shí)現(xiàn)一個淘寶搜索框輸入時,下拉智能彈出選項(xiàng)的案例
1. 要實(shí)現(xiàn)的UI效果
2. 實(shí)現(xiàn)步驟
2.1 獲取用戶輸入的搜索關(guān)鍵詞
為了獲取到用戶每次按下鍵盤輸入的內(nèi)容,需要監(jiān)聽輸入框的 keyup 事件。
并且給搜索輸入框框起一個 id 為 ipt,示例代碼如下:
keyup 事件,鼠標(biāo)彈起時觸發(fā)
2.2 建議搜索列表的函數(shù)封裝
將獲取搜索建議列表的代碼,封裝到 getSuggestList 函數(shù)中,示例代碼如下:
function getSuggestList(kw) {$.ajax({// 指定請求的 URL 地址,其中,q 是用戶輸入的關(guān)鍵字url: 'https://suggest.taobao.com/sug?q=' + kw,// 指定要發(fā)起的是 JSONP 請求dataType: 'jsonp',// 通過回調(diào)函數(shù)拿到j(luò)sonp返回回來的數(shù)據(jù)success: function(res) { renderSuggestList(res) }}) }2.3 渲染建議列表的UI結(jié)構(gòu)
2.3.1 定義搜索建議列表
在原HTML結(jié)構(gòu)基礎(chǔ)上,在搜索框的下方添加一個div盒子,取id名為“suggest-list”,如下所示:
<div class="box"><!-- tab 欄區(qū)域 --><div class="tabs"></div><!-- 搜索區(qū)域 --><div class="search-box"></div><!-- 搜索建議列表 --><div id="suggest-list"></div> </div>2.3.2 定義模板結(jié)構(gòu)
因?yàn)榻酉聛硪秩舅阉鹘ㄗh列表,在渲染數(shù)據(jù)結(jié)構(gòu)期間,我們最好使用模板引擎,因此必須要定義一個模板結(jié)構(gòu)。
A、導(dǎo)入模板引擎
<script src="./lib/template-web.js"></script>注:
本案例采用 art-template模板引擎
官方文檔:http://aui.github.io/art-template/zh-cn/docs/index.html
art-template 模板引擎詳細(xì)學(xué)習(xí)筆記:https://blog.csdn.net/zglibk/article/details/108048255
B、定義模板結(jié)構(gòu)
分析:
由上面2.2 的代碼"獲取用戶搜索建議列表" console.log(res)打印在控制臺的信息可以看到一個從服務(wù)器返回的result對象,在這個對象中有一個result數(shù)組,每循環(huán)一次可以拿到一個建議項(xiàng),里面每一個建議項(xiàng)又是一個數(shù)組,而實(shí)際上需要拿到的真正的建議內(nèi)容是索引(下標(biāo))為0的這一項(xiàng)。
——因此,我們只需要循環(huán)result這個數(shù)組,就能拿到每一個搜索鍵,由于每一個鍵都可以用{{$ value}}來表示,則{{$ value}}里索引為0這一項(xiàng),即為我們要獲取的 搜索建議內(nèi)容。
代碼實(shí)現(xiàn):
在模板引擎標(biāo)簽中,用{{each}} {{/each}}語法來循環(huán)result,每循環(huán)一次,就創(chuàng)建一個div標(biāo)簽(放搜索建議項(xiàng)),給div指定一個類名suggest-item,每循環(huán)一次就將 搜索建議內(nèi)容 打印出來:
2.3.1 定義渲染模板結(jié)構(gòu)的函數(shù)
封裝自定義函數(shù)renderSuggestList,調(diào)用函數(shù)渲染模板結(jié)構(gòu)。
// 渲染UI結(jié)構(gòu) // 傳入一個res參數(shù)(res就是待渲染的數(shù)據(jù)) function renderSuggestList(res) {// 判斷是否有待渲染的數(shù)據(jù),如果沒有就return出去,清空列表并隱藏if (res.result.length <= 0) {return $('#suggest-list').empty().hide();}// 調(diào)用模板引擎的template函數(shù)var htmlstr = template('tpl-suggestList', res) // 返回一個渲染好的html結(jié)構(gòu)// 將渲染好的字符串放到搜索建議列表div中,并展示出來$('#suggest-list').html(htmlstr).show(); }2.4 美化搜索建議列表
2.4.1 建議列表框美化
1)添加邊框效果
#suggest-list {border: 1px solid #ccc;/* 默認(rèn)隱藏 */display: none; }
2)列表項(xiàng)美化
2.5 輸入框的防抖
2.5.1 什么是防抖
防抖策略 (debounce)是當(dāng)事件被觸發(fā)后,延遲 n 秒 后再 執(zhí)行回調(diào),如果在這 n 秒內(nèi)事件又被觸發(fā),則 重新計(jì)時。
實(shí)現(xiàn)方式: 每次觸發(fā)事件時設(shè)置一個延遲調(diào)用方法,并且取消之前的延時調(diào)用方法;
缺 點(diǎn): 如果事件在規(guī)定的時間間隔內(nèi)被不斷的觸發(fā),則調(diào)用方法會被不斷的延遲。
函數(shù)防抖: 將多次操作合并為一次操作進(jìn)行。原理是維持一個計(jì)時器,規(guī)定在延遲時間后觸發(fā)函數(shù),但是在延遲時間內(nèi)再次觸發(fā)的話,就會取消之前的計(jì)時器而重新設(shè)置。這樣,就可以保證只有最后一次操作被觸發(fā)。
其原理圖示如下:
2.5.2 防抖的應(yīng)用場景
用戶在輸入框中連續(xù)輸入一串字符時,可以通過防抖策略。只在輸入完后,才執(zhí)行查詢的請求,這樣可以有效減少請求次數(shù),節(jié)約請求資源;
如果沒有防抖策略,那么每摁一下鍵盤,就會觸發(fā)一次網(wǎng)絡(luò)請求(如上圖)。
注:輸入框防抖,是最典型的應(yīng)用場景
2.5.3 實(shí)現(xiàn)輸入框的防抖
實(shí)現(xiàn)的步驟:
代碼實(shí)現(xiàn)的基本結(jié)構(gòu):
var timer = null // 1. 定義防動延時器 timer function debounceSearch(keywords) { // 2. 定義防抖的函數(shù)timer = setTimeout(function() {// 發(fā)起 JSONP 請求getSuggestList(keywords)}, 500) }$('#ipt').on('keyup', function() { // 3. 在觸發(fā) keyup 事件時,立即清空 timer clearTimeout(timer)// (...略)debounceSearch(keywords) })1)定義防抖延時器
var timer=null;2)定義防抖函數(shù)
// 定義防抖的函數(shù),延時500毫秒后,再請求數(shù)據(jù)接口 function debounceSearch(kw){// 開啟延時器timer = setTimeout(function(){getSuggestList(kw); ,500)}3)實(shí)現(xiàn)防抖
首先,在觸發(fā)keyup事件的時候,就要立即清空timer:
$('#ipt').on('keyup', function() {clearTimeout(timer);//( ......略 ) }然后,在獲取搜索建議列表函數(shù)這塊,就不能直接調(diào)用getsuggestList函數(shù),要將keyup事件函數(shù)調(diào)用做一下修改:
// 綁定用戶輸入框keyup事件$('#ipt').on('keyup', function() {// 清空timerclearTimeout(timer);var keywords = $(this).val().trim();if (keywords.length <= 0) {// 如果用戶沒有輸入內(nèi)容,則退出并清空隱藏列表return $('#suggest-list').empty().hide()}// getSuggestList(keywords); // 改為:debounceSearch(keywords); })
這樣,前面4次摁鍵(appl)的請求被取消,就只有最后1次(apple)才發(fā)起請求,實(shí)現(xiàn)了防抖
2.6 緩存搜索的建議列表
作用: 如果發(fā)起相同的請求,可以根據(jù)之前的緩存直接拿到搜索建議,就不用再重復(fù)發(fā)起請求,節(jié)約資源,提高搜索效率。
2.6.1 定義全局緩存對象
// 定義全局緩存對象var cacheObj={};2.6.2 將搜索結(jié)果保存到緩存對象中
function renderSuggestList(res) {//... 略去無關(guān)代碼// 1、獲取到用戶輸入的內(nèi)容,當(dāng)做鍵var k = $('#ipt').val().trim();// 2、將數(shù)據(jù)做為值緩存到全局對象中cacheObj[k] = res; }2.6.3 優(yōu)先從緩存對象中獲取搜索建議
代碼結(jié)構(gòu)如下:
// 監(jiān)聽文本框的 keyup 事件$('#ipt').on('keyup', function() {// ...省略其他代碼// 優(yōu)先從緩存中獲取搜索建議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><!-- 導(dǎo)入頁面的基本樣式 --><link rel="stylesheet" href="./css/search.css" /><!-- 導(dǎo)入 jQuery --><script src="./lib/jquery.js"></script><!-- 導(dǎo)入模板引擎 --><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><!-- 搜索區(qū)域(搜索框和搜索按鈕) --><div class="search-box"><input id="ipt" type="text" class="ipt" placeholder="請輸入要搜索的內(nèi)容" /><button class="btnSearch">搜索</button></div><!-- 搜索建議列表 --><div id="suggest-list"></div></div></div><!-- 模板結(jié)構(gòu) --><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 = {};// 定義防抖函數(shù),延時500毫秒后,再請求數(shù)據(jù)接口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) {// 如果用戶沒有輸入內(nèi)容,則退出并清空隱藏列表return $('#suggest-list').empty().hide()}// 發(fā)起請求之前,先判斷緩存里是否有數(shù)據(jù)if (cacheObj[keywords]) {return renderSuggestList(cacheObj[keywords]);}// TODO:獲取搜索建議列表// console.log(keywords);// 調(diào)用自定義函數(shù)// getSuggestList(keywords);debounceSearch(keywords);})// 獲取搜索建議的函數(shù)封裝function getSuggestList(kw) {$.ajax({url: 'https://suggest.taobao.com/sug?q=' + kw,// 發(fā)起JSONP請求dataType: 'jsonp',success: function(res) {renderSuggestList(res);}})}// 渲染UI結(jié)構(gòu)// 傳入一個res參數(shù)(res就是待渲染的數(shù)據(jù))function renderSuggestList(res) {// 判斷是否有待渲染的數(shù)據(jù),如果沒有就return出去,清空列表并隱藏if (res.result.length <= 0) {return $('#suggest-list').empty().hide();}// 調(diào)用模板引擎的template函數(shù)var htmlstr = template('tpl-suggestList', res); // 返回一個渲染好的html結(jié)構(gòu)// 將渲染好的字符串放到搜索建議列表div中,并展示出來$('#suggest-list').html(htmlstr).show();// 1、獲取到用戶輸入的內(nèi)容,當(dāng)做鍵var k = $('#ipt').val().trim();// 2、將數(shù)據(jù)做為值緩存到全局對象中cacheObj[k] = res;}})</script> </body></html>至此,整個案例完成。
全套案例 源碼 保存:
百度網(wǎng)盤:https://pan.baidu.com/s/1x9lVxBRxQplctihB1PRdnw 提取碼:1w9a
總結(jié)
以上是生活随笔為你收集整理的前端_网页编程 跨域与JSONP- 淘宝搜索案例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习笔记之数据可视化(二)—— 页面布局
- 下一篇: 2017年html5行业报告,云适配发布