如何在没有奇怪错误的情况下一起使用排序功能和搜索功能(regexp)?

时间:2016-07-09 07:44:57

标签: javascript jquery html regex sorting

在这个原型中,我有“产品”,每个产品都与它们的价格一起存储在一个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>

1 个答案:

答案 0 :(得分:0)

问题在于,当您在先前应用过滤器时对列表进行排序时,您只会移动数据,而不会移动这些数据的容器的可见性。

相反,每次根据当前排序顺序显示内容时,您都可以重新执行正则表达式匹配。这样您就可以确保始终可以看到正确的数据。

你的代码中有很多重复,有几个你有相同循环的地方,或者只有一个方面不同的代码。你应该总是试着不要重复自己&#34; (DRY)。

我建议只有一个功能来显示内容。你可以传递sort函数来应用它。请注意,这意味着HTML也会更改您指定事件处理程序的位置。还有许多其他这样的简化,太多了,无法提及。

检查此代码段:

&#13;
&#13;
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;
&#13;
&#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');