2

下面的功能允许用户通过 过滤产品data-attributes,并支持同时按多个值过滤。它通过创建一个包含所选值的数组来做到这一点,当单击任何值(在本例中为选中/未选中)时,它会隐藏所有项目,然后重新显示与更新数组中的值匹配的项目。

它在过滤 one 时可以正常工作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;
    });
});   
4

1 回答 1

1

您的两个处理程序都在更新selected数组,但只有一个处理程序在click. 如果颜色被(取消)选择,则为第一个,如果样式为第二个。假设您点击了“黑色”和“圆领”。那时您选择的数组将如下所示:[ "Black", "Crew_Neck" ]. 下次您进行选择时,假设您单击“Short Sleeves”,第二个(样式)处理程序将执行。这是正在发生的事情:

  1. Short_Sleeves 被添加到选定的数组中。
  2. 所有项目都使用隐藏$("#content").find("*").hide();
  3. 选定的数组将被迭代,并根据动态选择器再次显示项目。

3号是问题。在上面的示例中,单击了一个样式,因此样式处理程序正在执行。所选数组中的任何颜色项都将失败,因为例如,不会使用诸如$('#content').find('[data-style *="Black"]').show();.

我会建议两件事。

  1. 保留 2 组选择,一组用于颜色,一组用于样式。
  2. 组合您的代码以对两个组仅使用一个处理程序。

这是一个(大部分)工作示例

请注意,我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来简化上述条件。

更新小提琴

于 2013-03-27T07:10:25.110 回答