2016-05-15 58 views
1

在下面,有兩段代碼。用於無限滾動&搜索系統。一切正常,但搜索系統的問題是,如果我搜索了一些東西,那麼它會定位cardsboxes。他們應該在一條線上,如果你搜索它們,但那些有點起來等等。我還添加了一張關於這個的圖片。第二個問題是,我在我的網站上有一個無限滾動,但我認爲我將不得不改變搜索系統從JSON數據搜索,所以它會正常工作?我的意思是,你在搜索中鍵入內容,點擊輸入,然後從JSON搜索匹配,然後在container中顯示它們。我希望我清楚自己的問題,希望有人能幫助我解決問題。謝謝大家! :)Javascript - 修復搜索系統?

下面是一些CSS,以及:

的main.css - http://pastebin.com/Tgds0kuJ

ZMD分層顯示 - http://pastebin.com/Fn5JBpaQ

Materialise公司 - http://pastebin.com/ZxSGZtc8

這是正常的一張圖片:http://prntscr.com/b3yrwa

下面是圖片,如果我搜索它們:http://prntscr.com/b3yrub

這裏的無限滾動&卡

var perPage = 50; 

function paginate(items, page) { 
    var start = perPage * page; 
    return items.slice(start, start + perPage); 
} 
var condition = ''; 

function renderItems(pageItems) { 
    pageItems.forEach(function(item, index, arr) { 
     var message = 'BitSkins Price: $' + Math.round(item.bprice) + ''; 
     if (item.price !== null) { 
      if (item.bprice === '') { 
       message = 'Item never sold on BitSkins!'; 
      } 
      if (item.name != 'Operation Phoenix Case Key' && item.name != 'CS:GO Case Key' && item.name != 'Winter Offensive Case Key' && item.name != 'Revolver Case Key' && item.name != 'Operation Vanguard Case Key' && item.name != 'Operation Wildfire Case Key' && item.name != 'Shadow Case Key' && item.name != 'Operation Breakout Case Key' && item.name != 'Chroma Case Key' && item.name != 'Huntsman Case Key' && item.name != 'Falchion Case Key' && item.name != 'Chroma 2 Case Key') { 
       $("#inventory").html($("#inventory").html() + "<li class='col 2 zoomIn animated' style='padding:8px;font-weight:bold;font-size:13.5px'><div class='card item-card waves-effect waves-light' style='margin:0%;min-height:295px;width:245.438px;border-radius: 0px;height: 295px;box-shadow: inset 0px 0px 25px 2px #232323;border: 1px solid black' id='" + item.id + "'><div class='iteam' style='text-decoration: underline;text-align: left;font-size: 14.5px;color: #E8E8E8;font-family: Roboto;position: relative;right: -3px;'>" + item.name + "</div><div class='condition' style='text-align: left;color: #E8E8E8;font-family: Roboto;position: relative;left: 3px;'>" + item.condition + "</div><div class='center-align' style='position: relative;padding:0%;top: -33px;'><img title=\"" + item.originalname + "\" draggable='false' src='https://steamcommunity-a.akamaihd.net/economy/image/" + item.iconurl + "/235fx235f'></div><div class='secondarea' style='position: relative;top: -129px;background: rgba(0, 0, 0,0.15);display: block;height: 163px;'><div class='buyer-price center-align' style='font-size:22.5px;font-family: Arial Black;color:#E8E8E8'>$" + Math.round(item.price) + "<div class='bitskinscomp' style='font-weight: normal;font-size:12px;font-family: Roboto;font: bold;'>" + message + "</div></div><a class='btn waves-effect waves-light' style='position:relative;left:-5px;top:50px' href='" + item.inspect + "' target='_blank'>Inspect</a><a class='btn waves-effect waves-light' style='position:relative;right:-5px;top:50px' id='purchaseButton'>Cart</a></div></li>"); 
      } 
     } 
    }); 
} 
var win = $(window); 
var page = 0; 
renderItems(paginate(items, page)); 
win.scroll(function() { 
    if ($(document).height() - win.height() == win.scrollTop()) { 
     page++; 
     renderItems(paginate(items, page)); 
    } 
}); 

JavaScript的搜索系統

$('#SearchItemsFromList').keyup(function() { 
    var valThis = $(this).val().toLowerCase(); 
    if (valThis === "") { 
     $('#inventory > li > div').show(); 
    } else { 
     $('#inventory > li > div').each(function() { 
      var text = $(this).text().toLowerCase(); 
      (text.indexOf(valThis) >= 0) ? $(this).show(): $(this).hide(); 
     }); 
    } 
}); 

回答

0

概述

首先,我都是不可見的

...弄亂的卡或盒的定位...

,因爲我不知道你的CSS組成的,所以我乾脆上作出了一些猜測什麼。我懷疑這可能是由於您的物品的實際渲染。爲了解決這個問題,我從注入的標記中刪除了所有的CSS,因爲注入這些「樣式」屬性並不是最佳實踐,而且看起來您已經經歷過很難調試的情況。我做了一個嘗試,但你需要調整我提供的CSS,因爲它沒有包含所有你的CSS。

爲了解決這個問題,我只是簡單地用當前頁面進行「替換」,而不是每次追加,然後面對滾動/開始結束的挑戰,並處理搜索中斷。

我刪除了在按鈕上注射重複ID,而是改爲使用類注入。這將解決無效的HTML問題,這會在某些非常難以調試的情況下導致意想不到的結果。

更難的問題是在搜索頁面上的對象列表時,項目數組的動態特性。我已經通過創建一個名爲currentSearch的查看候選列表來解決這個問題,我可以自由地將其添加到名爲myApp.data的名稱爲myApp.data.currentSearch。說到命名空間,我這樣做是爲了避免多個全局對象。作爲最佳做法,我也將自己的定製功能做到了這一點。

這裏是我的樣品的標記,我用:

<div id="search"> 
    <input id="SearchItemsFromList" type="text" /> 
</div> 
<ul id="inventory"> 
</ul> 

CSS

這裏是一個很大一部分是從樣式屬性中提取的CSS。我冒昧地將它們命名爲first-style-thing class,second-style-thing等,它們只是與注入的元素序列相協調。這還具有減少注射線束尺寸的額外好處。

.li-style-thing { 
    padding: 8px; 
    font-weight: bold; 
    font-size: 13.5px; 
} 

.first-style-thing { 
    margin: 0%; 
    min-height: 295px; 
    width: 245.438px; 
    border-radius: 0px; 
    height: 295px; 
    box-shadow: inset 0px 0px 25px 2px #232323; 
    border: 1px solid black; 
} 

.second-style-thing { 
    text-decoration: underline; 
    text-align: left; 
    font-size: 14.5px; 
    color: #E8E8E8; 
    font-family: Roboto; 
    position: relative; 
    right: -3px; 
} 

.third-style-thing { 
    text-align: left; 
    color: #E8E8E8; 
    font-family: Roboto; 
    position: relative; 
    left: 3px; 
} 

.fourth-style-thing { 
    position: relative; 
    padding: 0%; 
    top: -33px; 
} 

.fifth-style-thing { 
    position: relative; 
    top: -129px; 
    background: rgba(0, 0, 0, 0.15); 
    display: block; 
    height: 163px; 
} 

.sixth-style-thing { 
    font-size: 22.5px; 
    font-family: Arial Black; 
    color: #E8E8E8; 
} 

.seventh-style-thing { 
    font-weight: normal; 
    font-size: 12px; 
    font-family: Roboto; 
    font: bold; 
} 

.eighth-style-thing { 
    position: relative; 
    left: -5px; 
    top: 50px; 
} 

.ninth-style-thing { 
    position: relative; 
    right: -5px; 
    top: 50px; 
} 

.btn { 
    position: relative; 
    display: block; 
    height: 1.5em; 
    width: 5em; 
    color: cyan; 
    background-color: blue; 
    font-weight: bold; 
    text-align: center; 
    padding-top: 0.5em; 
    margin: 1em; 
    text-decoration: none; 
    text-transform: uppercase; 
} 

#inventory { 
    display: block; 
    position: relative; 
    top: 1em; 
    left: 0em; 
    border: solid lime 1px; 
} 

#inventory li { 
    background-color: #888888; 
} 

#inventory li { 
    display: inline-block; 
    float: left; 
} 

.purchaseButton { 
    right: -8em; 
    top: 0; 
} 

#search { 
    height: 4em; 
    width: 100%; 
    background-color: #00aaaa; 
    padding: 1em; 
} 

代碼:

關於代碼,請注意我只是從逆向工程的注入代碼,並可能需要調整您的確切對象屬性作出的items對象。

請注意debounce函數,它解決了您可能經常觸發滾動/鼠標滾輪事件的問題。我添加了一個「油門」,你可以用它來代替,從這裏借用:https://remysharp.com/2010/07/21/throttling-function-calls說到,我在「scroll」事件中添加了「wheel」事件,所以如果你在滾動的頂部/底部,鼠標滾輪可以當沒有滾動實際發生時也會觸發滾動。我沒有提到其他可能的挑戰,例如當滾動位於頂部/底部時的向下/向上箭頭;我會根據你的需求讓你解決。

請注意,在輸入「搜索」事件時,我重置currentSearch列表。

我留下了一些console.log的地方,你可以刪除 - 但允許你看到頁面和一些事件火災記錄。

這裏是一個樣品所以你可以嘗試這一切了https://jsfiddle.net/MarkSchultheiss/hgfhh2y7/3/

var myApp = myApp || {}; 
myApp.data = { 
    currentSearch: [], 
    pageStart: 0, 
    pageEnd: 0,ma 
    perPage: 3, 
    page: 0, 
    lastScroll: 0, 
    scrollDelay: 250, 
    outputContainer: $('#inventory'), 
    excludes: ['Operation Phoenix Case Key', 'CS:GO Case Key', 'Winter Offensive Case Key', 'Revolver Case Key', 'Operation Vanguard Case Key', 'Operation Wildfire Case Key', 'Shadow Case Key', 'Operation Breakout Case Key', 'Chroma Case Key', 'Huntsman Case Key', 'Falchion Case Key', 'Chroma 2 Case Key'] 
}; 

myApp.func = { 
    contains: function(myArray, searchTerm, property) { 
    var found = []; 
    var len = myArray.length; 
    for (var i = 0; i < len; i++) { 
     if (myArray[i][property].toLowerCase().indexOf(searchTerm.toLowerCase()) > -1) found.push(myArray[i]); 
    } 
    return found; 
    }, 
    paginate: function(items) { 
    myApp.data.pageStart = myApp.data.perPage * myApp.data.page; 
    myApp.data.pageEnd = myApp.data.pageStart + myApp.data.perPage; 
    if (myApp.data.pageEnd > items.length) { 
     myApp.data.pageEnd = items.length; 
     myApp.data.pageStart = myApp.data.pageEnd - myApp.data.perPage >= 0 ? myApp.data.pageEnd - myApp.data.perPage : 0; 
    } 
    console.log("Page:" + myApp.data.page + " Start:" + myApp.data.pageStart + " End:" + myApp.data.pageEnd + " max:" + items.length); 
    return items; 
    }, 
    debounce: function(fn, delay) { 
    var timer = null; 
    return function() { 
     var context = this, 
     args = arguments; 
     clearTimeout(timer); 
     timer = setTimeout(function() { 
     fn.apply(context, args); 
     }, delay); 
    }; 
    }, 
    throttle: function(fn, threshhold, scope) { 
    threshhold || (threshhold = 250); 
    var last, 
     deferTimer; 
    return function() { 
     var context = scope || this; 
     var now = +new Date, 
     args = arguments; 
     if (last && now < last + threshhold) { 
     // hold on to it 
     clearTimeout(deferTimer); 
     deferTimer = setTimeout(function() { 
      last = now; 
      fn.apply(context, args); 
     }, threshhold); 
     } else { 
     last = now; 
     fn.apply(context, args); 
     } 
    } 
    }, 
    renderItems: function(pageItems) { 
    // $("#inventory").html(""); 
    console.log('renderStart Items:' + pageItems.length); 
    console.log(myApp.data.pageStart + ":" + myApp.data.pageEnd); 
    var renderList = pageItems.filter(function(itemValue) { 
     return !!(myApp.data.excludes.indexOf(itemValue) == -1) 
    }).slice(myApp.data.pageStart, myApp.data.pageEnd); 
    console.log(renderList); 
    var newContent = ""; 
    renderList.forEach(function(item, index, arr) { 
     var message = 'BitSkins Price: $' + Math.round((item.bprice * 1)); 
     if (item && item.price !== null) { 
     if (item.bprice === '') { 
      message = 'Item never sold on BitSkins!'; 
     } 
     if (myApp.data.excludes.indexOf(item.name) == -1) { 
      newContent += "<li class='col 2 zoomIn animated'><div class='card item-card waves-effect waves-light first-style-thing' id='" + item.id + "'><div class='iteam second-style-thing' >" + item.name + "</div><div class='condition third-style-thing'>" + item.condition + "</div><div class='center-align fourth-style-thing' ><img title='" + item.originalname + "' draggable='false' src='https://steamcommunity-a.akamaihd.net/economy/image/" + item.iconurl + "/235fx235f'></div><div class='secondarea fifth-style-thing'><div class='buyer-price center-align sixth-style-thing'>$" + Math.round(item.price) + "<div class='bitskinscomp seventh-style-thing'>" + message + "</div></div><a class='btn waves-effect waves-light eighth-style-thing' href='" + item.inspect + "' target='_blank'>Inspect</a><a class='btn waves-effect waves-light purchaseButton'>Cart</a></div></li>"; 
     } 
     } 
     myApp.data.outputContainer.html(newContent); 
    }); 

    } 
}; 

var items = [{ 
    id: "123", 
    name: "freddy Beer", 
    condition: "worn", 
    originalname: "beer stein", 
    price: 10.22, 
    bprice: "34.33", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "123", 
    name: "freddy Beer", 
    condition: "worn", 
    originalname: "beer stein", 
    price: 10.22, 
    bprice: "34.33", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "123", 
    name: "freddy Beer", 
    condition: "worn", 
    originalname: "beer stein", 
    price: 10.22, 
    bprice: "34.33", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "123", 
    name: "freddy Beer", 
    condition: "worn", 
    originalname: "beer stein", 
    price: 10.22, 
    bprice: "34.33", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "123", 
    name: "Operation Phoenix Case Key", 
    condition: "worn", 
    originalname: "Operation Phoenix Case Key", 
    price: 10.22, 
    bprice: "34.33", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "234", 
    name: "Johnson Wax", 
    condition: "waxy", 
    originalname: "Ear wax", 
    price: 2244.22, 
    bprice: "", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "45245", 
    name: "Door Knob | Green", 
    condition: "green tint", 
    originalname: "Green door knob", 
    price: 35.68, 
    bprice: "", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "45245red", 
    name: "Door Knob | Red", 
    condition: "red tint", 
    originalname: "Red door knob", 
    price: 35.68, 
    bprice: "", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "45245red", 
    name: "Door Knob | Red", 
    condition: "red tint", 
    originalname: "Red door knob", 
    price: 35.68, 
    bprice: "", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "45245blue", 
    name: "Door Knob | Blue", 
    condition: "blue tint", 
    originalname: "Blue door knob", 
    price: 35.68, 
    bprice: "", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "45245Brown", 
    name: "Door Knob | Brown", 
    condition: "brown tint", 
    originalname: "Brown door knob", 
    price: 35.68, 
    bprice: "34.23", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXU5A1PIYQNqhpOSV-fRPasw8rsQEl9Jg9SpIW1KgRrg6GGJWRBtI-ykYTak6WhN76JlWgFsJN1j72SotWiigbi-0BqYjuncdDDdRh-Pw9UqwY-SA", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "45245Malt", 
    name: "Beer malt | Brown", 
    condition: "brown tint", 
    originalname: "Brown Beer Malt ", 
    price: 35.68, 
    bprice: "34.23", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}, { 
    id: "4Beef", 
    name: "Beefeaters Mug | Brown", 
    condition: "new tint", 
    originalname: "Brown Beefeaters mug", 
    price: 35.68, 
    bprice: "34.23", 
    iconurl: "-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpot7HxfDhjxszJemkV08u_mpSOhcjnI7TDglRc7cF4n-T--Y3nj1H6-hBrMW_3LIOWdlU_MlGDqwO6wrvq15C6vp-bnHY36SAm4XbYl0SwhgYMMLJqUag1Og", 
    inspect: "http://example.com/myinspect/4" 
}]; 

myApp.data.outputContainer.on('customRenderEvent', function() { 
    myApp.func.renderItems(myApp.func.paginate(myApp.data.currentSearch)); 
}); 

$('#SearchItemsFromList').on('keyup', function() { 
    var valThis = $(this).val(); 
    if (valThis === "") { 
    // item-card 
    // items hold the things to pageinate 
    // currentSearch holds the filtered items 
    myApp.data.currentSearch = items; 
    } else { 
    // "name" is the matching property in the object 
    myApp.data.currentSearch = myApp.func.contains(items, valThis, "name"); 
    } 
    myApp.data.outputContainer.trigger('customRenderEvent'); 
    console.log("keyup len:" + myApp.data.currentSearch.length); 
}).trigger('keyup'); // trigger for initial display 

$(window).on('scroll wheel', myApp.func.debounce(function(event) { 
    // set the page on scroll up/down 
    if ($(this).scrollTop() == 0) { 
    myApp.data.page > 0 ? myApp.data.page-- : myApp.data.page = 0; 
    } else { 
    myApp.data.page++; 
    } 
    myApp.func.renderItems(myApp.func.paginate(myApp.data.currentSearch)); 
}, myApp.data.scrollDelay)); 

最後一點上的代碼,你有一個很長,難以維持的條件,我通過添加了一個數組替代排除,然後代碼使用它與一個過濾器:.filter(function(itemValue) { return !!(myApp.data.excludes.indexOf(itemValue) == -1) })

+0

我很抱歉,我沒有添加CSS代碼..我編輯了我的第一篇文章,並補充說。感謝您的幫助! –