我正在尝试构建一个复选框过滤器,该过滤器将根据这些元素上的多个data- *属性显示/隐藏元素。我已经做了几次尝试,但这些尝试都没有达到我想要的过滤效果。
我做了一个简单的小提琴:
$('input[type="checkbox"]').click(function() {
var $checked = $('input[type="checkbox"]:checked');
var $productItem = $('.productItem');
if ($checked.length > 0) {
$productItem.hide();
$checked.each(function() {
$('.productItem[data-level=' + this.value + ']').show();
$('.productItem[data-price=' + this.value + ']').show();
$('.productItem[data-network=' + this.value + ']').show();
});
} else {
$productItem.show();
}
});
我知道这段代码不正确,它就是我从一个小提琴开始从同一个墙上开始的地方。
我之后的过滤是"和"过滤您应用的过滤器越多,结果就越少。
例如,在小提琴中,如果你选择" gold"你只是获得金牌结果。如果你添加"银"过滤你获得金银,这是目前为止的好。因此,我在一个data- *属性中处于良好状态。
问题是,如果您添加了另一个数据 - *过滤器,例如,选择了金色和银色,请添加"网络A"过滤。在这种情况下,我希望将结果过滤为仅黄金和仅银元素,其中仅黄金/白银元素也具有network数据属性。
构建此类过滤的最佳方式是什么?因此,当应用价格过滤器时,它会过滤结果甚至更多?
答案 0 :(得分:1)
以下是您想要做的基本外壳
$('input[type="checkbox"]').click(function() {
var $checked = $('input[type="checkbox"]:checked');
var $items = $('.productItem');
var filters = {};
if ($checked.length) {
$('.productItem').hide();
$checked.each(function() {
filters[$(this).data('filter-type')] = $(this).val();
});
$items.each(function(i) {
for (var key in filters) {
if ($(this).data(key) == filters[key]) {
$(this).show();
}
}
});
} else {
$('.productItem').show();
}
});
让我看看能否以简单的方式解释这一点。您要完成的任务主要是将过滤器映射到产品列表。对于每个过滤器,仅显示与过滤器匹配的产品。为了实现这一点,我将过滤器存储为键/值对。过滤器的关键是过滤器类型(级别,价格或网络),并存储过滤器类型,我为每个复选框添加了数据属性data-filter-type
。因此,对于具有级别的过滤器类型的复选框,该属性将为data-filter-type="level"
。与现有的value
属性相结合,过滤器可以在JavaScript中作为键/值对整齐地表示:
data-filter-type: value
因此,当用户选择过滤器“platinum”和“network A”时,过滤器关联数组将如下所示:
{
level: platinum,
network: networkA
}
现在可以在filters数组中运行一个基本循环,并定位包含这些过滤器之一的所有项目。由于您的问题不够明确,我假设您想要or
关系,这意味着只有一个过滤器需要应用于该项目。如果您需要将所有选定的过滤器应用于每个项目,则需要相应地修改代码。
此代码的另一个问题是当过滤器添加到过滤器数组时:
filters[$(this).data('filter-type')] = $(this).val();
这仅在每个过滤器都是唯一的情况下才有效,也就是说,只检查每个过滤器中的一个。例如,如果选中了两个级别过滤器,则仅应用第二个过滤器,因为该密钥将被覆盖。您需要修改该部分以将两个值存储在同一个键下。每个键的基本值数组都可以完成这项任务。
正如我所说,这是一个很小的例子。肯定会有更多需要修复的案例,但我概述的一般步骤对你来说是一个很好的起点。祝你好运!
几乎忘记了小提琴的链接! http://jsfiddle.net/7ez8o1ra/3/
答案 1 :(得分:1)
我认为在应用后续条件之前,您需要在复选框中添加一个额外的属性,以明确定义$ productItem的顶级过滤器。我也改变了你的用户界面。隐藏过滤后的卡片对你的终端用户来说似乎是惩罚性的用户体验,所以灰卡(带有CSS不透明风格)似乎流动得更好,但也许这只是我...
<input type="checkbox" data-type="level" value="platinum" /> ...
<input type="checkbox" data-type="price" value="0-2" /> ...
<input type="checkbox" data-type="network" value="networkA" /> ...
...
$('input[type="checkbox"]').click(function() {
var $checked = $('input[type="checkbox"]:checked');
var $productItem = $('.productItem');
var filters = [];
var productFilter = '';
if ($checked.length > 0) {
$productItem.css('opacity',0.25);
$checked.each(function() {
dataType = $(this).attr('data-type');
if (!filters[dataType]) filters[dataType] = [];
filters[dataType].push(this.value);
});
for(var filterType in filters) {
for (i in filters[filterType]) {
productFilter += '[data-'+filterType+'="'+filters[filterType][i]+'"],';
}
productFilter = productFilter.replace(/,$/,'');
}
$productItem
.filter(productFilter)
.map(function() {
$(this).css('opacity',1);
});
} else {
$productItem.css('opacity',1);
}
});
请在此处查看小提琴:https://jsfiddle.net/7ez8o1ra/35/