前端_网页编程 跨域与JSONP- 淘宝搜索案例
文章目錄
- 前言
- 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 事件。
并且給搜索輸入框框起一個 id 為 ipt,示例代碼如下:
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,每循環一次就將 搜索建議內容 打印出來:
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)列表項美化
2.5 輸入框的防抖
2.5.1 什么是防抖
防抖策略 (debounce)是當事件被觸發后,延遲 n 秒 后再 執行回調,如果在這 n 秒內事件又被觸發,則 重新計時。
實現方式: 每次觸發事件時設置一個延遲調用方法,并且取消之前的延時調用方法;
缺 點: 如果事件在規定的時間間隔內被不斷的觸發,則調用方法會被不斷的延遲。
函數防抖: 將多次操作合并為一次操作進行。原理是維持一個計時器,規定在延遲時間后觸發函數,但是在延遲時間內再次觸發的話,就會取消之前的計時器而重新設置。這樣,就可以保證只有最后一次操作被觸發。
其原理圖示如下:
2.5.2 防抖的應用場景
用戶在輸入框中連續輸入一串字符時,可以通過防抖策略。只在輸入完后,才執行查詢的請求,這樣可以有效減少請求次數,節約請求資源;
如果沒有防抖策略,那么每摁一下鍵盤,就會觸發一次網絡請求(如上圖)。
注:輸入框防抖,是最典型的應用場景
2.5.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) })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- 淘宝搜索案例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学习笔记之数据可视化(二)—— 页面布局
- 下一篇: Java-While循环