以下功能允许用户按data-attributes
过滤产品,并同时适应多个值的过滤。它通过创建所选值的数组来完成此操作,并且当单击任何值时(在这种情况下选中/取消选中),它会隐藏所有项目,然后重新显示与更新的数组中的值匹配的项目。
在对一个data-attribute
进行过滤时,它可以正常工作,但当组合使用多个属性进行过滤时,它不再显示与任何值匹配的所有结果,而只显示与所有指定值匹配的结果。
我发布了一个小提琴,用于演示此处的问题:http://jsfiddle.net/chayacooper/WZpMh/94/除了其中一个项目之外的所有项目都具有data-style="V-Neck"
和data-color="Black"
的值,因此它们应保持可见选择了过滤器,但是如果隐藏了其他data-attribute
个项的其他值。
$(document).ready(function () {
var selected = [];
$('#attributes-Colors *').click(function () {
var attrColor = $(this).data('color');
var $this = $(this);
if ($this.parent().hasClass("active")) {
$this.parent().removeClass("active");
selected.splice(selected.indexOf(attrColor),1);
}
else {
$this.parent().addClass("active");
selected.push(attrColor);
}
$("#content").find("*").hide();
$.each(selected, function(index,item) {
$('#content').find('[data-color *="' + item + '"]').show();
});
return false;
});
$('#attributes-Silhouettes *').click(function () {
var attrStyle = $(this).data('style');
var $this = $(this);
if ($this.parent().hasClass("active")) {
$this.parent().removeClass("active");
selected.splice(selected.indexOf(attrStyle),1);
}
else {
$this.parent().addClass("active");
selected.push(attrStyle);
}
$("#content").find("*").hide();
$.each(selected, function(index,item) {
$('#content').find('[data-style *="' + item + '"]').show();
});
return false;
});
});
答案 0 :(得分:1)
两个处理程序都在更新selected
数组,但只有一个处理程序在click
上执行。第一个是颜色被选中(de),第二个是样式。假设你点击了“黑色”和“圆领”。那时您选择的数组将如下所示:[ "Black", "Crew_Neck" ]
。下次进行选择时,假设您单击“Short Sleeves”,第二个(样式)处理程序执行。这是正在发生的事情:
Short_Sleeves
会添加到所选数组中。$("#content").find("*").hide();
3号是问题所在。在上面的示例中,单击了一个样式,因此样式处理程序正在执行。所选数组中任何颜色的项目都将失败,因为例如,$('#content').find('[data-style *="Black"]').show();
等选择器不会找到任何元素。
我会建议两件事。
这是(大部分)工作example。
请注意,我在data-type="color|style"
容器中添加了.filterOptions
,以允许组合使用单个处理程序,并且仍然知道哪个组已更改。
这是完整的脚本:
$(document).ready(function () {
// use 2 arrays so the combined handler uses correct group
var selected = { color: [], style: [] };
// code was similar enough to combine to 1 handler for both groups
$('.filterOptions').on("click", "a", function (e) {
// figure out which group...
var type = $(e.delegateTarget).data("type");
var $this = $(this);
// ...and the value of the checkbox checked
var attrValue = $this.data(type);
// same as before but using 'type' to access the correct array
if ($this.parent().hasClass("active")) {
$this.parent().removeClass("active");
selected[type].splice(selected[type].indexOf(attrValue),1);
}
else {
$this.parent().addClass("active");
selected[type].push(attrValue);
}
// also showing all again if no more boxes are checked
if (attrValue == 'All' || $(".active", ".filterOptions").length == 0) {
$('#content').find('*').show();
}
else {
// hide 'em all
$("#content").find("*").hide();
// go through both style and color arrays
for (var key in selected) {
// and show any that have been checked
$.each(selected[key], function(index,item) {
$('#content').find('[data-' + key + ' *="' + item + '"]').show();
});
}
}
});
});
更新:纳入评论建议
要使处理程序使用复选框而不是链接,这是对事件绑定代码的一个小改动。它现在使用change
方法而不是click
并且侦听:checkbox
元素而不是a
:
$('.filterOptions').on("change", ":checkbox", function (e) {
// handler code
});
“全部”选项“打嗝”比我想象的要困难得多。这就是我最终的结果:
// get a jQuery object with all the options the user selected
var checked = $(":checked", ".filterOptions");
// show all of the available options if...
if (checked.length == 0 // ...no boxes are checked
|| // ...or...
checked.filter(".all").length > 0) // ...at least one "All" box is checked...
{
// remainder of code, including else block, unchanged
}
我还在适当的all
元素中添加了checkbox
类,以简化上述条件。