在这个原型中,我有“产品”,每个产品都与它们的价格一起存储在一个div中。我添加了四个按钮,按字母顺序(A-Z和Z-A)以及按价格(从最低到最高,从最高到最低)对包含产品的div进行排序。这些排序功能可以完美地完成。我还有一个搜索栏作为搜索引擎,如果你喜欢在输入字段中输入每个字符,如果它们不包含那个字母,将按名称删除产品(div)。我使用正则表达式完成了这个。这也是有效的,直到我调整它以尝试与分拣机制一起工作。
问题
我希望能够使用搜索功能搜索“产品”,以显示正确的结果,无论产品的排序顺序如何。
问题
如何能够只显示包含搜索栏中搜索到的字母的div,无论顺序如何(例如Z到A)。
我认为我通过添加index
变量来破坏搜索功能本身,但你不能list.name[i].match(res)
吗?搜索功能背后的逻辑有问题。我认为需要认真修复的功能是searchProducts
功能。
我改编搜索产品功能后的代码如下......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<div id="resultsSpan"></div>
<div id="product0" style="height:60px; width:60px; background-color:blue;"></div>
<div id="product1" style="height:60px; width:60px; background-color:blue;"></div>
<div id="product2" style="height:60px; width:60px; background-color:blue;"></div>
<div id="product3" style="height:60px; width:60px; background-color:blue;"></div>
<button onclick="sortprods()">
Sort A-Z
</button>
<button onclick="sortprods2()">
Sort Z-A
</button>
<button onclick="sortprods3()">
Price (low to high)
</button>
<button onclick="sortprods4()">
Price (high to low)
</button>
<input type="text" id="searchbar" onkeyup="searchProducts()"/>
</body>
</html>
<script>
var list = [
{name: "Apple", price: 31},
{name: "Banana", price: 22},
{name: "Orange", price: 46},
{name: "Strawberry", price:76}
];
list.sort(AtoZ);
for (var i = 0; i<list.length; i++) {
document.getElementById("product" + i).innerHTML = list[i].name + ", " + list[i].price;
}
function AtoZ(a,b) {
if (a.name < b.name)
return -1;
if (a.name > b.name)
return 1;
return 0;
}
function ZtoA(a,b) {
if (a.name < b.name)
return 1;
if (a.name > b.name)
return -1;
return 0;
}
function LowtoHigh(a,b) {
if (a.price < b.price)
return -1;
if (a.price > b.price)
return 1;
return 0;
}
function HightoLow(a,b) {
if (a.price < b.price)
return 1;
if (a.price > b.price)
return -1;
return 0;
}
function sortprods(){
list.sort(AtoZ);
currentSort = "AtoZ";
for (var i = 0; i < list.length; i++) {
document.getElementById("product" + i).innerHTML = list[i].name + ", " + list[i].price;
}
}
function sortprods2(){
list.sort(ZtoA);
currentSort = "ZtoA";
for (var j = 0; j < list.length; j++) {
document.getElementById("product" + j).innerHTML = list[j].name + ", " + list[j].price;
}
}
function sortprods3(){
currentSort = "LowtoHigh";
list.sort(LowtoHigh);
for (var k = 0; k < list.length; k++) {
document.getElementById("product" + k).innerHTML = list[k].name + ", " + list[k].price;
}
}
function sortprods4(){
currentSort = "HightoLow";
list.sort(HightoLow);
for (var l = 0; l < list.length; l++) {
document.getElementById("product" + l).innerHTML = list[l].name + ", " + list[l].price;
}
}
var input = "";
var index = [];
var currentSort = "AtoZ";
function searchProducts(){
input = document.getElementById("searchbar").value;
if(input == ""){
document.getElementById("product0").style.display = "block";
document.getElementById("product1").style.display = "block";
document.getElementById("product2").style.display = "block";
document.getElementById("product3").style.display = "block";
}else{
switch(currentSort){
case "AtoZ":
list.sort(AtoZ);
for(var a = 0; a < list.length; a++){
document.getElementById("product" + a).innerHTML = list[a].name + ", " + list[a].price;
index.push(list[a].name);
}
index.sort();
break;
case "ZtoA":
list.sort(ZtoA);
for(var b = 0; b < list.length; b++){
document.getElementById("product" + b).innerHTML = list[b].name + ", " + list[b].price;
index.push(list[b].name);
}
index.sort();
index.reverse();
break;
case "LowtoHigh":
list.sort(LowtoHigh);
for(var c = 0; c < list.length; c++){
index.push(list[c].price);
}
index.sort(function(a, b){return a-b});
break;
case "HightoLow":
list.sort(HightoLow);
for(var d = 0; d < list.length; d++){
index.push(list[d].price);
}
index.sort(function(a, b){return b-a});
break;
}
test = input;
re = new RegExp(test, 'gi');
for(var e=0; e<index.length; e++){
if(index[e].match(re)){
document.getElementById("product"+e).style.display = "block";
}else{
document.getElementById("product"+e).style.display = "none";
}
}
}
}
</script>
在我调整searchProducts
函数(完全适应之前完成工作)之前的代码是......
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<input type="text" id="searchbar" onkeyup="searchProducts()"/>
<div id="demo"></div>
<div id="demo2">
<div id="product1" style="background-color:red; height:100px; width:100px; float:left">chocolate<br /><button onClick="grow()" id="button1">Show Info</button></div>
<div id="product2" style="background-color:blue; height:100px; width:100px; float:left">Mint</div>
<div id="product3" style="background-color:green; height:100px; width:100px; float:left">Caramel</div>
</div>
</body>
</html>
<script>
var index = ["Chocolate", "Mint", "Caramel"];
var input = "";
var currentLog = [];
function searchProducts(){
currentLog = [];
input = document.getElementById("searchbar").value;
/*function searchStringInArray(str, strArray){
for (var j = 0; j < strArray.length; j++) {
if (strArray[j].match(str)){
var temp = strArray.slice(j, (j + 1));
currentLog.push(temp);
console.log(j);
}
}
document.getElementById("demo").innerHTML = currentLog.join("<br />");
if(currentLog.length < 1){
document.getElementById("demo").innerHTML = "No results were found.";
}
}*/
test = input;
re = new RegExp(test, 'gi');
/*if(!index[0].match(re)){
document.getElementById("product1").style.display = "none";
}
if(!index[1].match(re)){
document.getElementById("product2").style.display = "none";
}
if(!index[2].match(re)){
document.getElementById("product3").style.display = "none";
}*/
for(var e=0; e<index.length; e++){
if(!index[e].match(re)){
document.getElementById("product"+(e+1)).style.display = "none";
}else{
document.getElementById("product"+(e+1)).style.display = "block";
}
}
if(document.getElementById("product1").style.display == "none" && document.getElementById("product2").style.display == "none" && document.getElementById("product3").style.display == "none"){
document.getElementById("demo").innerHTML = "no results";
}else{
document.getElementById("demo").innerHTML = "";
}
/*searchStringInArray(input, index);*/
}
function grow(){
if(document.getElementById('product1').style.height == "200px"){
document.getElementById('product1').style.height = '100px';
document.getElementById('button1').innerHTML = "Show Info";
}else{
document.getElementById('product1').style.height = "200px";
document.getElementById('button1').innerHTML = "Hide Info";
}
}
</script>
答案 0 :(得分:0)
问题在于,当您在先前应用过滤器时对列表进行排序时,您只会移动数据,而不会移动这些数据的容器的可见性。
相反,每次根据当前排序顺序显示内容时,您都可以重新执行正则表达式匹配。这样您就可以确保始终可以看到正确的数据。
你的代码中有很多重复,有几个你有相同循环的地方,或者只有一个方面不同的代码。你应该总是试着不要重复自己&#34; (DRY)。
我建议只有一个功能来显示内容。你可以传递sort函数来应用它。请注意,这意味着HTML也会更改您指定事件处理程序的位置。还有许多其他这样的简化,太多了,无法提及。
检查此代码段:
var list = [
{name: "Apple", price: 31},
{name: "Banana", price: 22},
{name: "Orange", price: 46},
{name: "Strawberry", price:76}
];
var currentRegex = /./; // any character matches
var currentSort = AtoZ;
// Call the function we have for applying the initial sort order and filter
searchProducts(document.getElementById('searchbar').value);
// Shorter ways to compare:
function AtoZ(a,b) { return a.name < b.name ? -1 : a.name > b.name ? 1 : 0; }
function ZtoA(a,b) { return AtoZ(b,a) }
function LowtoHigh(a,b) { return a.price - b.price }
function HightoLow(a,b) { return b.price - a.price }
// One function for all sort orders: pass sort order as function
function sortprods(sorter) {
var showCount = 0;
currentSort = sorter;
list.sort(currentSort);
for (var i = 0; i < list.length; i++) {
var product = document.getElementById("product" + i);
// use textContent, not innerHTML
product.textContent = list[i].name + ", " + list[i].price;
var show = !!list[i].name.match(currentRegex);
product.style.display = show ? "" : "none";
showCount += show;
}
document.getElementById('resultsSpan').textContent =
showCount ? '' : 'no results';
}
function searchProducts(input){
// Argument is value of input
// No need to `switch` on currentSort. Can do this with generic code.
// Deal with empty input by using all-matching `.` regexp.
// `g` not needed.
currentRegex = new RegExp(input.length ? input : '.', 'i');
sortprods(currentSort);
}
&#13;
<div id="resultsSpan"></div>
<div id="product0" style="height:45px; width:60px; background-color:lightblue;"></div>
<div id="product1" style="height:45px; width:60px; background-color:lightblue;"></div>
<div id="product2" style="height:45px; width:60px; background-color:lightblue;"></div>
<div id="product3" style="height:45px; width:60px; background-color:lightblue;"></div>
<button onclick="sortprods(AtoZ)">Sort A-Z</button>
<button onclick="sortprods(ZtoA)">Sort Z-A</button>
<button onclick="sortprods(LowtoHigh)">Price (low to high)</button>
<button onclick="sortprods(HightoLow)">Price (high to low)</button>
<input type="text" id="searchbar" onkeyup="searchProducts(this.value)"/>
&#13;
您在评论中询问ternary operator:
product.style.display = list[i].name.match(currentRegex) ? "" : "none";
以上相当于:
var temp;
if (list[i].name.match(currentRegex)) {
temp = "";
} else {
temp = "none";
}
product.style.display = temp;
...除了当然没有创建temp
变量。
另一种情况:
currentRegex = new RegExp(input.length ? input : '.', 'i');
......相当于:
var temp;
if (input.length) { // if length is defined and not 0
temp = input;
} else {
temp = ".";
}
currentRegex = new RegExp(temp, 'i');