Javascript 如何使用jQuery过滤多个select组的结果?

Javascript 如何使用jQuery过滤多个select组的结果?,javascript,jquery,html,refactoring,filtering,Javascript,Jquery,Html,Refactoring,Filtering,我有两个选项,我正在尝试从现在开始筛选,但稍后将添加第三个选项,可能还会添加第四个选项(例如:现在我在价格和评论之间筛选,但希望在列表中添加更多价格,以及另一个筛选类别,如“评级”,由3、4或5颗星组成) 使用我在下面列出的逻辑可以很好地工作,但我觉得随着时间的推移,它会变得非常漫长和复杂(而且是不必要的)。我知道有一种方法可以重构代码我只是想知道最好的方法是什么? HTML: 希望你能看到我想要什么,谢谢你的任何意见 *EDIT:jsfiddle:我可以想出两种不同的方法来简化代码并使其更易于

我有两个选项,我正在尝试从现在开始筛选,但稍后将添加第三个选项,可能还会添加第四个选项(例如:现在我在价格和评论之间筛选,但希望在列表中添加更多价格,以及另一个筛选类别,如“评级”,由3、4或5颗星组成)

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

希望你能看到我想要什么,谢谢你的任何意见


*EDIT:jsfiddle:

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

  • 您可以根据条件通过算法推导出应该隐藏或显示哪些项

  • 您可以创建一个条件和操作表,这样添加一个新的条件和操作就是向表中添加一个新项

  • 更改HTML,使其自我描述应该显示的内容

  • 以下是表驱动方法的外观:

    $('.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();
        } 
    });
    

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

    要获得动态结果,标准化命名是最好的方法。 首先标准化条件选择器,为它们提供一个通用类,并使用id属性进行区分。还建议遵循值的命名转换。这将产生类似于

        <select id="deal" class="criteriaSelector">
          <option value="all">All deals</option>
          <option value="50">$50</option>
          <option value="25">$25</option>
        </select>
    
        <select id="review" class="criteriaSelector">
          <option value="all">All reviews</option>
          <option value="positive">Positive reviews</option>
          <option value="negative">Negative reviews</option>
        </select>
    

    现在,只要遵循命名约定,添加新的条件选择器就不需要对这段代码进行更改。

    您能为requiremnet发布JSFIDLE吗。。这可能更容易操作on@SarahM-我添加了第三个更简单的选项。在它中,您可以使选项自我描述它们应该显示/过滤的内容,这样代码就不必执行该操作。jfriend,非常感谢您的帮助和输入。两种回答都非常有效。
    $('.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();
        } 
    });
    
    $('.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-");
        }
    });
    
      <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>
    
     $('.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();
    });
    
        <select id="deal" class="criteriaSelector">
          <option value="all">All deals</option>
          <option value="50">$50</option>
          <option value="25">$25</option>
        </select>
    
        <select id="review" class="criteriaSelector">
          <option value="all">All reviews</option>
          <option value="positive">Positive reviews</option>
          <option value="negative">Negative reviews</option>
        </select>
    
        <div class="item review-positive deal-25"></div>
        <div class="item review-negative deal-50"></div>
    
        $('.criteriaSelector').change(function() {
          // Initialize criteria string
          var criteria = '';
          // Set value for all selector
          var showAll = true;
    
          // Iterate over all criteriaSelectors
          $('.criteriaSelector').each(function(){
            // Get value
            var val = $(this).children(':selected').val();
            // Check if this limits our results
            if(val !== 'all'){
              // Append selector to criteria
              criteria += '.' + $(this).attr('id') + '-' + val;
              // We don't want to show all results anymore
              showAll = false;
            }
          });
          // Check if results are limited somehow
          if(showAll){
            // No criterias were set so show all
            $('.item').show();
          } else {
            // Hide all items
            $('.item').hide();
            // Show the ones that were selected
            $(criteria).show();
          }
    
        });