javascript - 如何使用 jQuery 过滤具有多个选择组的结果?

标签 javascript jquery html refactoring filtering

我现在有两个选项正在尝试过滤,但稍后会添加第三个或第四个选项(例如:现在我正在价格和评论之间进行过滤,但我想添加更多价格列表和另一个过滤器类别,如“评级”,由 3、4 或 5 星组成)。

使用我在下面列出的逻辑工作正常,但我觉得它会变得非常冗长和复杂(并且不必要)。我知道有一种方法可以重构代码 我只是想知道最好的方法是什么? HTML:

  <select class="deals">
    <option value="deals-all">All deals</option>
    <option value="50">$50</option>
    <option value="25">$25</option>
  </select>

  <select class="reviews">
    <option value="reviews-all">All reviews</option>
    <option value="reviews-positive">Positive reviews</option>
    <option value="reviews-negative">Negative reviews</option>
  </select>

jQuery

 $('.reviews, .deals').change(function() {

var reviewsVal = $('.reviews :selected').val();
var dealsVal = $('.deals :selected').val();



 if((reviewsVal == 'reviews-all') && (dealsVal == 'deals-all')) {

      $('.review-positive').show();
 $('.review-negative').show();
 $('.deals-25').show();
 $('.deals-50').show();
 } 


else if((dealsVal == '50') && (reviewsVal == 'reviews-positive')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').show();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').hide();

 }

 else if((dealsVal == '50') && (reviewsVal == 'reviews-negative')) {
 $('.review-negative.deals-50').show();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').hide();
 }

else if((dealsVal == '25') && (reviewsVal == 'reviews-positive')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').show();
}

else if((dealsVal == '25') && (reviewsVal == 'reviews-negative')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').show();
 $('.review-positive.deals-25').hide();
}

 else if((dealsVal == 'deals-all') && (reviewsVal == 'reviews-positive')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').show();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').show();
}

else if((dealsVal == 'deals-all') && (reviewsVal == 'reviews-negative')) {
 $('.review-negative.deals-50').show();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').show();
 $('.review-positive.deals-25').hide();
}

else if((dealsVal == '50') && (reviewsVal == 'reviews-all')) {
 $('.review-negative.deals-50').show();
 $('.review-positive.deals-50').show();
 $('.review-negative.deals-25').hide();
 $('.review-positive.deals-25').hide();
}

else if((dealsVal == '25') && (reviewsVal == 'reviews-all')) {
 $('.review-negative.deals-50').hide();
 $('.review-positive.deals-50').hide();
 $('.review-negative.deals-25').show();
 $('.review-positive.deals-25').show();
}

else {
 $('.review-positive').show();
 $('.review-negative').show();
 $('.deals-25').show();
 $('.deals-50').show();
} 
});

$('.reviews-positive').click(function() {
$('.review-negative').hide();
$('.review-positive').show();
});

$('.reviews-negative').click(function() {
$('.review-positive').hide();
$('.review-negative').show();
});


});​

希望您能明白我的意思,感谢您的任何输入。

*编辑:jsfiddle:http://jsfiddle.net/TXywp/1/

最佳答案

我可以想到两种不同的方法来简化代码并使其更易于维护和扩展:

  1. 您可以根据条件通过算法得出应隐藏或显示哪些项目。

  2. 您可以创建条件和操作表,以便添加新条件和操作只是向表中添加新项目。

  3. 更改您的 HTML,使其能够 self 描述应显示的内容。

这是表驱动方法的样子:

$('.reviews, .deals').change(function() {

    var allDeals = '.review-negative.deals-50, .review-positive.deals-50, .review-positive.deals-25, .review-negative.deals-25';

    var table = [
        {rv: 'reviews-all', dv: 'deals-all', show: '.review-positive, .review-negative, .deals-25, .deals-50'},
        {rv: 'reviews-positive', dv: '50', show: '.review-positive.deals-50'},
        {rv: 'reviews-negative', dv: '50', show: '.review-negative.deals-50'},
        {rv: 'reviews-positive', dv: '25', show: '.review-positive.deals-25'}
        {rv: 'reviews-negative', dv: '25', show: '.review-negative.deals-25'},
        {rv: 'reviews-positive', dv: 'deals-all', show: '.review-positive.deals-50, .review-positive.deals-25'},
        {rv: 'reviews-negative', dv: 'deals-all', show: '.review-negative.deals-50, .review-negative.deals-25'},
        {rv: 'reviews-all', dv: '50', show: '.review-negative.deals-50, .review-positive.deals-50'},
        {rv: 'reviews-all', dv: '25', show: '.review-negative.deals-25, .review-positive.deals-25'}
    ];

    var reviewsVal = $('.reviews :selected').val();
    var dealsVal = $('.deals :selected').val();

    $(allDeals).hide();

    var item, found = false;
    for (var i = 0, len = table.length; i < len; i++) {
        item = table[i];
        if (dealsVal == item.dv && reviewsVal == item.rv) {
            $(item.show).show();
            found = true;
            break;
        }
    }

    if (!found) {
        $('.review-positive, .review-negative, .deals-25, .deals-50').show();
    } 
});

还有一种算法方法,让您只需向数组中添加一个新条目即可添加新的交易值(value)。如果只有两个交易,这可能比表驱动方法需要更多工作,但如果您有 4 个或更多交易级别,这将更易于维护。

$('.reviews, .deals').change(function() {
    var deals = ['25', '50'];

    function addAllDeals(base, prefix) {
        for (var i = 0; i < deals.length; i++) {
            if (base) base += ", ";
            base += prefix + deals[i];
        }
        return(base);
    }

    function addSingleDeal(prefixes, deal) {
        var sel = [];
        for (var i = 0; i < prefixes.length; i++) {
            sel.push(prefixes[i] + deal);
        }
        return(sel.join(", ");
    }

    var reviewsVal = $('.reviews :selected').val();
    var dealsVal = $('.deals :selected').val();
    var itemsToShow = "";

    // hide everything to start
    var initialHide = addAllDeals("", ".review-positive.deals-");
    initialHide = addAllDeals(initialHide, ".review-negative.deals-");
    $(initialHide).hide();

    if (reviewsVal == 'reviews-all') {
        if (dealsVal == 'deals-all') {
            itemsToShow = addAllDeals(".review-positive, .review-negative", ".deals-");
        } else {
            itemsToShow = addSingleDeal([".review-negative.deals-", ".review-negative.deals-"], dealsVal);
        }
    } else if (reviewsVal == 'reviews-positive') {
        itemsToShow = '.review-positive.deals-' + dealsVal;
    } else if (reviewVal == 'reviews-negative') {
        itemsToShow = '.review-negative.deals-' + dealsVal;
    } else {
        itemsToShow = addAllDeals(".review-positive, .review-negative", ".deals-");
    }
});

如果您可以将您的 HTML(如我上面的第三个选项)更改为:

  <select class="deals">
    <option value="deals-all" data-base=".review-positive, .review-negative">All deals</option>
    <option value="50" data-base=".deals-50">$50</option>
    <option value="25" data-base=".deals-25">$25</option>
  </select>

  <select class="reviews">
    <option value="reviews-all" data-filter="">All reviews</option>
    <option value="reviews-positive" data-filter=".review-positive">Positive reviews</option>
    <option value="reviews-negative" data-filter=".review-negative">Negative reviews</option>
  </select>

然后,您可以只使用这个简单的 javascript:

 $('.reviews, .deals').change(function() {

    var dealsBase = $('.deals :selected').data("base");
    var reviewsFilter = $('.reviews :selected').data("filter");

     // hide all
     $(".review-negative, .review-positive").hide();

     // show the desired ones
     var base = $(dealsBase);
     if (reviewsFilter) {
         base = base.filter(reviewsFilter);
     }
     base.show();
});

警告:由于您没有提供您的代码/HTML 的有效 jsFiddle 示例来尝试此操作,因此尚未运行或检查此代码是否存在输入错误。但是,希望您了解这两种方法。

关于javascript - 如何使用 jQuery 过滤具有多个选择组的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12499282/

相关文章:

javascript - Node readline 接口(interface)以乘法方式重复每个字符

javascript - 如何解决“未定义的错误 "Uncaught TypeError: Cannot call method 'changePage”

javascript - 如何使用 jQuery 隐藏所有接下来的 "fieldset"元素?

javascript - 如何让 Loading div 在所有链接和脚本加载之前出现

html - Bootstrap 3 即使在使用 respond.js 后也无法在 IE 8 中运行

javascript - d3js : How to pass button id to onclick callback function

javascript - 事件处理程序没有响应

javascript - 如何在我的 HTML 页面上打印带有颜色语法高亮显示的 HTML 代码?

javascript - 如何将悬停替换为单击

jquery - 当div滚动到页面顶部时隐藏div