apicloud搜尋框的實現與踩坑
要求如下圖:
一、實現思路:
1、開啟frame時,獲取儲存的資料(getStorage),放入建立的陣列中,遍歷該陣列將item展示出來。有記錄時,顯示記錄,沒有記錄時顯示空;
2、最多十條記錄,記錄用 setStorage 儲存起來,並放在陣列中,最後搜尋的記錄在最前面;後面搜尋的記錄如果之前有,刪除之前的記錄,在陣列第一條新增。每點選一次 search (軟鍵盤搜尋鍵),記錄一條。
3、點選記錄時,內容顯示在 input 輸入框中,並直接搜尋;被電擊的該條資料放到陣列第一位。
4、點選垃圾桶圖示,清空陣列和被快取的資料
二、踩坑環節:
1. 在開發中開發者在除錯時快取往往沒能清空
(我在apploader上除錯沒有什麼好的清除快取的方法,只有2個選擇:
第一,需要清除快取時,程式碼最前加 $api.clearStorage(),同步到手機一次;然後去掉該程式碼,重新進入一次。
第二,解除安裝apploader,重新安裝,因為多次解除安裝安裝,安裝包先不刪除。)
2. 使用者在剛剛開始使用app時,是沒有任何快取的資料的,並且沒有 keyWord 這個索引值。此時開啟frame 獲取不到快取會報錯。對此,可以在開啟frame 時setStorage傳入一個快取值,在存入陣列時將該資料刪除即可。
if(!$api.getStorage('keyWord')){
$api.setStorage('keyWord', '孍');
}
此處最好傳入生僻字,以免使用者重複到該詞。
3. 這一點是我在開發中遇到的最難受的bug,當 arrHistory 值為空時,系統判定它不為陣列,所以要先將它轉化成陣列:
// 載入歷史搜尋 var searchHistory = []; function hasHistory(){ searchHistory = $api.getStorage('keyWord'); if(JSON.stringify(arrHistory)=='undefined'){ searchHistory += ' '; searchHistory = searchHistory.split(','); } if(searchHistory.length==1 && searchHistory[0]=='孍' || searchHistory.length==0 ||!searchHistory){ $api.byId('history-box').innerHTML = ''; }else{ var historyHtml = ''; historyHtml += '<p>' +'<span class="history fs14 pl5 c000">歷史搜尋</span>' +'<i class="iconfont icon-lajitongshanchu history-icon fs18" onclick="clearHistory()" Tapmode></i>' +'</p>' +'<div class="history-list fs12">'; for(var i in arrHistory){ historyHtml += '<span class="history-item item" onclick="historyItemToList('+i+')">'+arrHistory[i]+'</span>'; } historyHtml += '</div>'; $api.byId('history-box').innerHTML = historyHtml; } }
js程式碼中宣告的 var arrHistory=[ ] 陣列,在函式中讀取到為 undefined,這是因為在剛剛進入時沒有快取值可獲取。設定了剛進入就初始一個快取值就行。
以下程式碼將監聽到的 關鍵詞 存入陣列並存入快取中,此時通過arrHistory=$api.getStorage('keyWord');獲取到的 arrHistory 是有問題的,不是陣列型別,不能直接使用;也不是字串型別,所以要先轉化成字串型別,再用split 轉化為陣列型別。再對陣列進行操作,加入新的關鍵詞到陣列最前,刪除不必要的關鍵詞。
// 監聽 win 頁面的關鍵詞
function listenShopKeyWord(page) {
api.addEventListener({
name: 'shopkeyWord'
}, function(ret, err){
keyWord = ret.value.keyWord;
if(keyWord){
document.getElementById("listData").innerHTML = '';
searchKeyWord(keyWord, page);
commonGetStorage(keyWord);
}else{
hasHistory();
}
});
}
// 搜尋關鍵字function searchKeyWord(keyWord, page){
api.ajax({
url: url,
method: 'post',
dataType: 'json',
data: {
values: params
}
},function(){
if(ret){
//正常處理 或 展示搜尋結果
}else{
alert('請求錯誤');
}
});
}
// 搜尋函式公用
function commonGetStorage(content){
if($api.getStorage('SEARCH_KEY')){
searchHistory = $api.getStorage('keyWord');
searchHistory += '';
searchHistory = searchHistory.split(',');
} else {
searchHistory = [];
}
// 搜尋的長度
var SEARCH_MAX_LENGTH = 10;
insertArray(
searchHistory,
content,
SEARCH_MAX_LENGTH
);
$api.setStorage('keyWord', searchHistory);
}
// 比較新的 keyWord 與原陣列,選擇新增方式
function insertArray(arr, val, maxLen) {
// 先查詢陣列有沒有val 值
var index = arr.indexOf(val);
// 如果是第一條資料就不做操作
if (index === 0) {
return
}
// 如果有 val值 就先刪掉再插入
if (index > 0) {
arr.splice(index, 1)
}
// 沒有就直接插入
arr.unshift(val);
// 去除 第一個預設歷史值
var i = arr.length-1;
if(arr[i]=='孍'){
arr.splice(i, 1);
}
if(arr[i]==''){
arr.splice(i, 1);
}
// 超過陣列的最大數量就把最後一個刪掉
if (maxLen && arr.length > maxLen) {
arr.pop();
}
}
// 點選歷史搜尋跳轉到list
function historyItemToList(i){
var keyWord = searchHistory[i];
api.sendEvent({
name: 'shopClickItem', //然後在 win 頁面監聽此事件並獲取到 keyWord ,將關鍵詞放到input
extra: {
keyWord: keyWord
}
});
}
// 清除歷史搜尋
function clearHistory(){
document.getElementById('listData').innerHTML = '';
searchHistory = ['孍'];
$api.setStorage('keyWord', []);
}
function searchKeyWord(keyWord, page){
api.ajax({
url: url,
method: 'post',
dataType: 'json',
data: {
values: params
}
},function(){
if(ret){
//正常處理 或 展示搜尋結果
}else{
alert('請求錯誤');
}
});
}
// 搜尋函式公用
function commonGetStorage(content){
if($api.getStorage('SEARCH_KEY')){
searchHistory = $api.getStorage('keyWord');
searchHistory += '';
searchHistory = searchHistory.split(',');
} else {
searchHistory = [];
}
// 搜尋的長度
var SEARCH_MAX_LENGTH = 10;
insertArray(
searchHistory,
content,
SEARCH_MAX_LENGTH
);
$api.setStorage('keyWord', searchHistory);
}
// 比較新的 keyWord 與原陣列,選擇新增方式
function insertArray(arr, val, maxLen) {
// 先查詢陣列有沒有val 值
var index = arr.indexOf(val);
// 如果是第一條資料就不做操作
if (index === 0) {
return
}
// 如果有 val值 就先刪掉再插入
if (index > 0) {
arr.splice(index, 1)
}
// 沒有就直接插入
arr.unshift(val);
// 去除 第一個預設歷史值
var i = arr.length-1;
if(arr[i]=='孍'){
arr.splice(i, 1);
}
if(arr[i]==''){
arr.splice(i, 1);
}
// 超過陣列的最大數量就把最後一個刪掉
if (maxLen && arr.length > maxLen) {
arr.pop();
}
}
// 點選歷史搜尋跳轉到list
function historyItemToList(i){
var keyWord = searchHistory[i];
api.sendEvent({
name: 'shopClickItem', //然後在 win 頁面監聽此事件並獲取到 keyWord ,將關鍵詞放到input
extra: {
keyWord: keyWord
}
});
}
// 清除歷史搜尋
function clearHistory(){
document.getElementById('listData').innerHTML = '';
searchHistory = ['孍'];
$api.setStorage('keyWord', []);
}
因為 searchHistory 為空會報錯,所以只能賦個偏僻字,用 $api.setStorage('keyWord', []); 而不用 clearStorage 清空快取是因為 app 中快取往往不止這一類。
最後,感覺自己目前寫的這些並不令人滿意,待有更高質量的程式碼再來更新。同行如果有更好的方法,希望留言一起探討,一起進步。