如何使用 jQuery 和 CSS 过滤具有多个值的列表?

Posted

技术标签:

【中文标题】如何使用 jQuery 和 CSS 过滤具有多个值的列表?【英文标题】:How can I filter a list having multiple values using jQuery and CSS? 【发布时间】:2015-08-17 19:25:25 【问题描述】:

在测试了这里和网络其他地方的各种解决方案后,我无法弄清楚以“简单”方式(或让它工作)的逻辑。

我有以下清单:

<ul class="store-list">
    <li data-categories="Bags Shoes Accessories Belts">
        <h3 itemprop="name">Enzo Poli</h3>
    </li>
    <li data-categories="Womenswear Shoes">
        <h3 itemprop="name">Ilse Jacobsen</h3>
    </li>
    <li data-categories="Menswear Womenswear Shoes Ties">
        <h3 itemprop="name">Kiman (Shoes Ties)</h3>
    </li>
    <li data-categories="Menswear Womenswear Shoes Knitwear">
        <h3 itemprop="name">Riccovero</h3>
    </li>
</ul>

<button class="a">Ties</button>
<button class="b">Ties & Shoes</button>
<button class="c">Menswear</button>

我尝试过使用Attribute Not Equal Selector,但这绝对行不通。

var stores = $('.store-list');

$('button.b').on('click', function()
  stores.find('li[data-categories!="Ties"][data-categories!="Shoes"]').fadeOut();  
);

另一个问题是当我选择不同的类别时,隐藏的元素没有显示出来。

我知道我可以使用$.each() 并遍历每个元素并使用大量代码来查看它是否包含类别并检查它是否可见。但我只是希望有更好、更简单的替代方案。

所以 Q 是;如何根据我选择的过滤器显示/隐藏列表项?See my fiddle here。

【问题讨论】:

点击button时,预期结果是否只显示一个li元素? 没有。我有大约 13 个类别。如果我选择 3 个类别,将显示具有这些类别的所有项目。其他所有内容都应隐藏。 尝试使用.filter();虽然可以替代将data-* 添加到button 元素以针对button 进行测试.innerhtml 【参考方案1】:

试试这个:

var stores = $('.store-list');

$('button.a').on('click', function() 
  stores.find('li').not('[data-categories~="Ties"]').fadeOut();
  stores.find('li[data-categories~="Ties"]').fadeIn();
);

$('button.b').on('click', function() 
  stores.find('li').not('[data-categories~="Ties"], [data-categories~="Shoes"]').fadeOut();
  stores.find('li[data-categories~="Ties"], [data-categories~="Shoes"]').fadeIn();
);

$('button.c').on('click', function() 
  stores.find('li').not('[data-categories~="Menswear"]').fadeOut();
  stores.find('li[data-categories~="Menswear"]').fadeIn();
);
body 
  font-size: 0.7em;

ul,
li 
  list-style: none;

a 
  text-decoration: none;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul class="store-list">
  <li data-categories="Bags Shoes Accessories Belts">
    <h3 itemprop="name">Enzo Poli</h3>
  </li>
  <li data-categories="Womenswear">
    <h3 itemprop="name">Ilse Jacobsen</h3>
  </li>
  <li data-categories="Menswear Womenswear Shoes Ties">
    <h3 itemprop="name">Kiman (Shoes Ties)</h3>
  </li>
  <li data-categories="Menswear Womenswear Shoes Knitwear">
    <h3 itemprop="name">Riccovero</h3>
  </li>
</ul>

<button class="a">Ties</button>
<button class="b">Ties & Shoes</button>
<button class="c">Menswear</button>

如您所见,我使用data~='item' 而不是!=,这样它会检查它是否在数据属性中包含该单词。

另外,我强制淡入具有该类别的那些,以便完成所有管理。当然有更好的方法来做到这一点,但这是默认逻辑。

【讨论】:

现在我们使用~=检查data-categories是否包含A or B。如果我想拥有A and B,我该怎么办? @Steven 删除[data-categories~="Ties"], [data-categories~="Shoes"] 中的逗号并使用[data-categories~="Ties"][data-categories~="Shoes"] 并检查A and B,而使用逗号检查A or B 这是我现在使用的,但它会选择任何有男装 鞋的商店。不是男装鞋。【参考方案2】:

我认为这里应该归咎的误解是 data-* 属性的工作方式类似于通过空格分隔多个值的类。不是这样,在这里您只是将 arbtirary data-categories 属性设置为包含空格的单个字符串,因此尝试匹配任何给定的单个类别可能不起作用。顺便说一句,您可以遍历所有元素并将它们的 data-categories 属性与您的目标进行模式匹配,例如:

$('button.a').on('click', function()
    stores.find('li').each(function() 
        if($(this).attr("data-categories").split(" ").indexOf('Ties') == -1) 
           $(this).fadeOut();
        
    );
);

实际上,更好的方法可能是使用类而不是数据属性,然后您可以轻松地根据没有类进行选择。

【讨论】:

【参考方案3】:

var stores = $('ul.store-list > li');

$('button.a').on('click', function()
    stores.fadeIn(':hidden').not('li[data-categories~="Ties"]', stores).fadeOut();  
);

$('button.b').on('click', function()
   stores.fadeIn(':hidden').not('li[data-categories~="Shoes"], li[data-categories~="Ties"]', stores).fadeOut();  
);

$('button.c').on('click', function()
   stores.fadeIn(':hidden').not('li[data-categories~="Menswear"]', stores).fadeOut();  
);
body 
    font-size: 0.7em;


ul, li 
    list-style: none;

a  text-decoration: none; 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="store-list">
    <li data-categories="Bags Shoes Accessories Belts">
        <h3 itemprop="name">Enzo Poli</h3>
    </li>
    <li data-categories="Womenswear ">
        <h3 itemprop="name">Ilse Jacobsen</h3>
    </li>
    <li data-categories="Menswear Womenswear Shoes Ties">
        <h3 itemprop="name">Kiman (Shoes Ties)</h3>
    </li>
    <li data-categories="Menswear Womenswear Shoes Knitwear">
        <h3 itemprop="name">Riccovero</h3>
    </li>
</ul>

<button class="a">Ties</button>
<button class="b">Ties & Shoes</button>
<button class="c">Menswear</button>

【讨论】:

您好!如果您提供有关您的答案将如何解决问题中的问题的背景信息,您的答案可能对提问者和整个社区更有帮助。 ***.com/help/how-to-answer 虽然在一行中工作,但您可以看到元素在再次隐藏之前是如何显示的。这使列表“跳跃”,而 Joel 的解决方案使这变得顺利。【参考方案4】:

绝对不能使用.fadeIn() - 所以一旦它们消失了,它们就消失了。

没有一个数据类别使用单个值,因此检查=!= 永远不会给出完全匹配,使用~= 来匹配单词:

https://api.jquery.com/attribute-contains-word-selector/

[Joel 提供了代码的答案,所以停在这里]

【讨论】:

以上是关于如何使用 jQuery 和 CSS 过滤具有多个值的列表?的主要内容,如果未能解决你的问题,请参考以下文章

从jQuery中的多个相同的类名中获取值CSS

具有多个数据属性的 jQuery 过滤器 div

过滤具有多个值的字段

使用 Pandas 过滤具有多个值的单元格中的字符串

具有多个过滤器的 JQuery Mobile 可过滤列表视图

使用多个过滤器值过滤对象