具有嵌套循环的过滤器列表:如果第一个循环成功完成,则执行某些操作
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>
这可能是一个愚蠢的问题,但我真的无法理解它。 我正在实现一个过滤器,它由 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>