具有嵌套循环的过滤器列表:如果第一个循环成功完成,则执行某些操作

filter list with nested loop: if first loop finish successfully, do something

这可能是一个愚蠢的问题,但我真的无法理解它。 我正在实现一个过滤器,它由 select 输入组成,它应该 select divs 具有保存在 data-* 属性中的给定值。

我使用嵌套循环这样做:我首先遍历所有 div,然后列出来自 select 输入的所有给定值。 如果甚至 select 中的一个值都不匹配,我将继续下一个 div。 如果是这样,我将转到 select 输入值数组的下一个值。 我快到那里了,我错过了最后的一小步,那就是: 当我循环完 select 中的所有值并且它们都与我的 div 的数据属性匹配时,我应该显示这个 div。 我不知道我应该把代码放在哪里来显示这个 div!

这是我的(简化)代码。请不要评论我如何使用 javascript,我知道它也可以完美地工作,但我不能使用这个项目所以它必须在 jQuery.

html:

<select class="filter">
  <option value="01">1</option>
  <option value="02">2</option>
  <option value="03">3</option>
</select>

<select class="filter">
  <option value="jan">Jan</option>
  <option value="feb">feb</option>
  <option value="march">march</option>
</select>

<div class="list-item" data-day="01" data-month="jan">01 jan </div>
<div class="list-item" data-day="02" data-month="feb">02 feb </div>
<div class="list-item" data-day="03" data-month="jan">03 jan </div>
<div class="list-item" data-day="02" data-month="march">02 march </div>
<div class="list-item" data-day="03" data-month="jan"> 03 jan</div>

jQuery:

function combinedFilters() {
  var valuesArray = [];
  var items = jQuery('.list-item');

  jQuery('select').each(function() {
    valuesArray.push(jQuery(this).val());
  });

  console.log(valuesArray);

  jQuery(items).each(function(i, item) {

    if (jQuery(this).data('month') && jQuery(this).data('day') ) {
      var month = jQuery(this).data('month');
      var day = jQuery(this).data('day').toString();

      jQuery.each(valuesArray, function(i, value) {
        if (value != null) {
        console.log(value);

          if (value == month || value == day) {
            return true; // keep looping into values Array
          } else {
            return false; //go out of the Values loop to the next div
          }
        }
        //jQuery(this).show();
        console.log('show the div');
      });
    }

  });
}


function trigger() {
  jQuery('select').change(function() {

    jQuery('.list-item').hide();
    combinedFilters();

  });
}

jQuery('.list-item').hide();
trigger();

还有一个 jsFiddle:https://jsfiddle.net/n2x5yc9g/1/

非常感谢任何带解释的建议!

更新:

根据@Michal Młoźniak 提出的解决方案,我修复了我的过滤器,如果有人对最终结果感兴趣,这里是完整代码: https://codepen.io/designbygio/pen/NRxvWo

这对你有用吗?或者你真的需要嵌套循环吗?

function combinedFilters() {
  var valuesArray = [];
  var items = jQuery('.list-item');

  jQuery('select').each(function() {
    valuesArray.push(jQuery(this).val());
  });

  items.each(function(i, item) {
    if (jQuery(item).data('month') === valuesArray[1] && jQuery(item).data('day') === valuesArray[0] ) {
      jQuery(item).show();
    }
  });
}

function trigger() {
  jQuery('select').change(function() {

  jQuery('.list-item').hide();
    combinedFilters();
  });
}

jQuery(function() {
  jQuery('.list-item').hide();
  trigger();
});

为了只显示 div 的数据日和数据月对应于第一个和第二个 select 标签中的值 selected 一个快速的方法可以是:

jQuery('select').change(function() {
  jQuery('.list-item').hide();
  var day = jQuery('select:eq(0)').val();
  var month = jQuery('select:eq(1)').val();
  $('.list-item[data-day="' + day + '"][data-month="' + month + '"]').show();

  // for inverted values, if they are
  $('.list-item[data-day="' + month + '"][data-month="' + day + '"]').show();
});
jQuery('.list-item').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<select class="filter">
    <option value="01">1</option>
    <option value="02">2</option>
    <option value="03">3</option>
</select>

<select class="filter">
    <option value=""></option>
    <option value="jan">Jan</option>
    <option value="feb">feb</option>
    <option value="march">march</option>
</select>

<div class="list-item" data-day="01" data-month="jan">01 jan </div>
<div class="list-item" data-day="02" data-month="feb">02 feb </div>
<div class="list-item" data-day="03" data-month="jan">03 jan </div>
<div class="list-item" data-day="02" data-month="march">02 march </div>
<div class="list-item" data-day="03" data-month="jan"> 03 jan</div>

更新

根据评论:

the null value means the filter wasn't selected so in your example if user select "1" and don't select "month" i should see all the divs with data-day=1 and don't care about data-month

新代码段是:

jQuery('select').change(function() {
  jQuery('.list-item').hide();
  var day = jQuery('select:eq(0)').val();
  var month = jQuery('select:eq(1)').val();
  $('.list-item').filter(function(i, e) {
    var lDay = $(this).data('day');
    var lMonth = $(this).data('month');

    if ((day.length == 0 || day == lDay) && (month.length == 0 || month == lMonth)) {
      return true;
    }
    return false;
  }).show();
});
jQuery('.list-item').hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<select class="filter">
    <option value=""></option>
    <option value="01">1</option>
    <option value="02">2</option>
    <option value="03">3</option>
</select>

<select class="filter">
    <option value=""></option>
    <option value="jan">Jan</option>
    <option value="feb">feb</option>
    <option value="march">march</option>
</select>

<div class="list-item" data-day="01" data-month="jan">01 jan </div>
<div class="list-item" data-day="02" data-month="feb">02 feb </div>
<div class="list-item" data-day="03" data-month="jan">03 jan </div>
<div class="list-item" data-day="02" data-month="march">02 march </div>
<div class="list-item" data-day="03" data-month="jan"> 03 jan</div>