修改功能以同时过滤多个数据属性

时间:2013-03-27 04:04:56

标签: javascript jquery find custom-data-attribute

以下功能允许用户按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;
    });
});   

1 个答案:

答案 0 :(得分:1)

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

  1. Short_Sleeves会添加到所选数组中。
  2. 使用$("#content").find("*").hide();
  3. 隐藏所有项目
  4. 迭代所选数组,并根据动态选择器再次显示项目。
  5. 3号是问题所在。在上面的示例中,单击了一个样式,因此样式处理程序正在执行。所选数组中任何颜色的项目都将失败,因为例如,$('#content').find('[data-style *="Black"]').show();等选择器不会找到任何元素。

    我会建议两件事。

    1. 保留2个选择数组,一个用于颜色,一个用于样式。
    2. 将您的代码合并为两个组仅使用一个处理程序。
    3. 这是(大部分)工作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类,以简化上述条件。

      Updated Fiddle