2016-05-15 82 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代码..我编辑了我的第一篇文章,并补充说。感谢您的帮助! –