构建复选框过滤器的最佳方式,以显示/隐藏基于多个data-*属性的元素
Best way to build checkbox filter to show/hide elements based on multiple data-* attributes
我试图建立一个复选框过滤器,将显示/隐藏基于这些元素上的多个数据*属性的元素。我已经做了几次尝试,但都没有达到我想要的过滤效果。
我做了一个简单的操作:
http://jsfiddle.net/7ez8o1ra/$('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();
}
});
我知道这段代码是不正确的,这就是我从头开始的地方。
我所追求的过滤是一个"answers"过滤器,你应用的过滤器越多,你通常得到的结果就越少。
例如,在小提琴中,如果你选择"gold",你只会得到金色的结果。如果你添加"银"过滤器,你会得到金和银,目前为止还不错。所以我在一个data-*属性中很好。
问题是,如果您添加另一个data-*过滤器,例如,选择黄金和白银,添加"网络A"过滤器。在这种情况下,我希望将结果过滤到仅金元素和仅银元素,并且仅金/银元素也具有网络A数据属性。
构建这种过滤的最佳方法是什么?当应用价格过滤器时,它会过滤更多的结果。
下面是一个基本的shell
$('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
。因此,对于过滤器类型为level的复选框,属性将是data-filter-type="level"
。再加上现有的value
属性,过滤器可以在JavaScript中整齐地表示为键/值对:
data-filter-type: value
因此,当用户选择过滤器"白金"answers"网络A"时,过滤器关联数组看起来像:
{
level: platinum,
network: networkA
}
现在可以在过滤器数组中运行一个基本循环,并针对包含这些过滤器之一的所有项。由于您的问题不明确,我假设您需要or
关系,这意味着只需要将一个过滤器应用于该项目。如果您需要将所有选定的筛选器应用于每个项,则需要相应地修改代码。
这段代码的另一个问题是当过滤器被添加到过滤器数组时:
filters[$(this).data('filter-type')] = $(this).val();
这只在每个过滤器是唯一的情况下才会起作用,也就是说,每个过滤器只检查一个。例如,如果检查了两个级别的过滤器,则只应用第二个过滤器,因为键将被覆盖。您需要修改该部分以将两个值存储在同一键下。每个键的基本值数组就可以完成这项工作。
正如我所说,这是一个最小的例子。当然,您还需要解决更多的问题,但我概述的一般步骤是一个很好的起点。好运!
差点忘了小提琴链接!http://jsfiddle.net/7ez8o1ra/3/
我认为您需要向复选框添加一个额外的属性,以便在应用后续标准之前显式地为$productItem定义顶级过滤器。我还更改了你的UI。对于最终用户来说,隐藏过滤过的卡片似乎是一种惩罚性的用户体验,所以将卡片变灰(带有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/
- 如何将返回的值应用于多个不同位置的多个选择器
- JQuery多个隐藏值
- 插件总是只得到最后一个实例,如何让它适用于多个元素
- 使jQuery自动完成功能适用于多个单词(“跳过”一个单词)
- 保存到视图中的多个隐藏字段
- 将jQuery应用于多个不同的动态创建的HTML元素
- 多个隐藏的全屏分区
- Javascript:将类应用于多个 Id 用于交互式地图
- 无法获得$q.所有工作都致力于多个承诺
- 有没有一种纯粹的Javascript方法可以将一个函数应用于多个元素的事件
- 将悬停时将 CSS 应用于多个组件
- 如何使这个js适用于多个项目
- 我怎样才能让 sinon 屈服于多个回调
- JQuery 将一段代码应用于多个元素
- jQuery UI 可排序函数是否同时适用于多个表
- jQuery - 将方法应用于多个对象
- 将挖空.js模型应用于多个图元
- 如何使onEdit()触发器函数应用于多个工作表
- 一个功能适用于多个按钮
- 隐藏表列依赖于多个动态json数组中的按钮