使用css规则过滤元素 - 如何增加特异性

时间:2016-07-20 10:35:48

标签: css filter

前提

我的容器中包含<div class="event-item">类型的元素(n> 500),其中每个元素的属性都为 a b c 以及a1,a2,... b1,b2等的值。例如

<div class="event-item" data-a="1" data-b="1" data-c="2">
<div class="event-item" data-a="2" data-b="7" data-c="2">
<div class="event-item" data-a="1" data-b="5" data-c="2">
<div class="event-item" data-a="4" data-b="2" data-c="1">
<div class="event-item" data-a="8" data-b="3" data-c="1">

现在,我在UI中实现过滤器,以便用户可以动态隐藏与规则不匹配的元素。用户界面如下所示:

Filters in action

E.g。如果启用了过滤器B的值3和5,则仅显示与这两个值匹配的项目。单击&#34;重置过滤器...&#34;将禁用此过滤器,取消选中值3和5.过滤器&#39;逻辑组合应为 AND ,这意味着如果过滤器A值1处于活动状态且过滤器B值3处于活动状态,则元素必须应用 BOTH 条件才能显示。否则他们会被隐藏。

我就是这样做的,为什么这是一个问题

假设,如果过滤器A的值3被检查,我会添加类&#34; .filtered-a&#34;到事件项的容器。同时,我添加了课程&#34; .preserved-a&#34;对所有具有数据-a =&#34; 3&#34;的事件项目。相应的css是:

#eventlist.filtered-a .event-item{display:none;}
#eventlist.filtered-a .event-item.preserved-a{display:inline-block;}

因此,我扩展了过滤器B和C的css。当使用一个过滤器时,它就像一个魅力。但是,当多个过滤器处于活动状态时,事件项必须仅匹配一个过滤规则才能显示,使逻辑组合为 OR

我尝试了什么

我尝试了一个包含多个类组合的css解决方案:

#eventlist.filtered-a .event-item,
#eventlist.filtered-b .event-item,
#eventlist.filtered-c .event-item,
#eventlist.filtered-a.filtered-b .event-item,
#eventlist.filtered-a.filtered-c .event-item,
#eventlist.filtered-b.filtered-c .event-item,
#eventlist.filtered-a.filtered-b.filtered-c .event-item{display:none;}

#eventlist.filtered-a .event-item.preserved-a,
#eventlist.filtered-b .event-item.preserved-b,
#eventlist.filtered-c .event-item.preserved-c,
#eventlist.filtered-a.filtered-b .event-item.preserved-a.preserved-b,
#eventlist.filtered-a.filtered-c .event-item.preserved-a.preserved-c,
#eventlist.filtered-b.filtered-c .event-item.preserved-b.preserved-c,
#eventlist.filtered-a.filtered-b.filtered-c .event-item.preserved-a.preserved-b.preserved-c{display:inline-block;}

...希望父元素上的多个类会增加css特性,但实际情况并非如此。此外,这个解决方案非常难看,如果实现第四个参数,css将是一场噩梦。

这是我的jquery进行过滤(仅示例性过滤器a)

$("#eventlist").removeClass("filtered-a");
$("#eventlist .event-item").removeClass("preserved-a");

$(".eventlist-filter-a input").each(function(){
  if($(this).is(":checked")){
    $("#eventlist").addClass("filtered-a");
    $("#eventlist .event-item."+$(this).val()).addClass("preserved-a");
  } 
});

我必须保留与过滤器匹配的元素,而不是隐藏元素,因为我使用$()。each()迭代过滤器列表的输入元素的方式。

问题

如何基于css类有效地实现过滤功能。

1 个答案:

答案 0 :(得分:0)

<强>解决方案

我找到了一种通过主动隐藏过滤元素来反转机制的解决方案。 jquery:

// reset filters
$("#eventlist *").removeClass("filtered-a filtered-b filtered-c");

// apply filters
if(filter = $(".eventlist-filter-a input:checked").map(function(){ return "." + $(this).val(); }).get().join()){    
  $("#eventlist .event-item").not(filter).addClass("filtered-a");
}

说明:该函数获取所有已选中复选框的值,并从中创建一个jquery选择器。选择器被反转(这里不是()),所有匹配的元素都得到类&#34;过滤&#34;。这可以针对所有三个过滤器完成,每个人都很高兴;)

css简化为:

#eventlist .event-item{display:inline-block; font-size:13px;line-height:20px;}
#eventlist .event-item.filtered-a{display:none}