【问题标题】:JS/jQuery - Check if element has all classes in arrayJS/jQuery - 检查元素是否包含数组中的所有类
【发布时间】:2020-09-01 09:06:20
【问题描述】:

我有一个<ul> 的项目
然后我有一组要过滤的类。
现在我想遍历所有 <li> 并仅显示包含数组中 all 类的项并隐藏所有其他项。

我该怎么做?

到目前为止的代码(未经测试):

JS

define([
    "jquery"
], function($){
    "use strict";

    function main(config, element) {

        $('.filter-option').on('change', function (event) {

            const activeFilters = $('.filter-option:checked');

            if (!activeFilters) {
                $('.product').forEach(function(item) {
                    item.show();
                });
            } else {
                $('.product').forEach(function(item) {
                    //if item has all classes from activeFilters id's show else hide
                });
            }
        });
    }
    return main;
});

HTML

<div class="filter-box">
    <h3>Size</h3>
    <input type="checkbox" class="filter-option" id="size-s" name="size-s">
    <label for="size-s" class="filter-option-label">Small</label>
    <input type="checkbox" class="filter-option" id="size-m" name="size-m">
    <label for="size-m" class="filter-option-label">Medium</label>
    <input type="checkbox" class="filter-option" id="size-l" name="size-l">
    <label for="size-l" class="filter-option-label">Large</label>
    <h3>Colour</h3>
    <input type="checkbox" class="filter-option" id="color-white" name="color-white">
    <label for="color-white" class="filter-option-label">White</label>
    <input type="checkbox" class="filter-option" id="color-red" name="color-red">
    <label for="color-red" class="filter-option-label">Red</label>
    <input type="checkbox" class="filter-option" id="color-blue" name="color-blue">
    <label for="color-blue" class="filter-option-label">Blue</label>
</div>
<ul id="product-list">
    <li class="product color-red size-l">Red Large</li>
    <li class="product color-red size-m">Red Medium</li>
    <li class="product color-red size-s">Red Small</li>
    <li class="product color-blue size-l">Blue Large</li>
    <li class="product color-blue size-m">Blue Medium</li>
    <li class="product color-blue size-s">Blue Small</li>
    <li class="product color-white size-l">White Large</li>
    <li class="product color-white size-m">White Medium</li>
    <li class="product color-white size-s">White Small</li>
</ul>

【问题讨论】:

  • 请向我们展示所有相关代码,Html,css,jquery。
  • 包含我的代码

标签: javascript jquery dom requirejs


【解决方案1】:

假设你有这样的东西并想要一个 VanillaJS 解决方案:

<div id="list-container">
    <ul>
        <li class="example">One</li>
        <li class="example another-class">Two</li>
        <li class="example">Three</li>
        <li class="example">Four</li>
        <li class="example">Five</li>
    </ul>
</div>

您可以迭代 &lt;li&gt; 元素并像这样检查类:

// Required classes array
let reqClasses = ['example', 'another-class'];

// Function to check if the element has the required classes
const hasClasses = (item) => {
   var s = true;
   
   reqClasses.forEach((classname) => {
      if (!item.classList.contains(classname) && s) {
         s = false;
      }
   });
  
   return s;
}

// We get the <li> elements
let list = document
   .getElementById("list-container")
   .querySelectorAll('li');

// We call the function on each element and toggle visibility depending on the return
list.forEach((item) => {
   if (!hasClasses(item)) {
      item.style.display = 'none';
   }
});

【讨论】:

  • 您在最后一个forEach 中缺少)。其次,当我运行您的代码时,它会隐藏所有 li
  • @Carsten 你说得对,我用正确的源更新了源代码。
  • 难道不能删除“s”并遍历所需的类并在不适合时立即返回 false 吗?既然我需要所有课程来匹配?还有可能只是:1.隐藏所有内容 2. jQuery 选择所有必需类的所有内容 3. 显示选择我会尝试你的代码,谢谢!
  • 结束了,这是基于您的回答:jsfiddle.net/Chazlol/mqg851tc/3
【解决方案2】:

现在这样解决了:

更新:必须将过滤器从 AND 调整为 OR。
为此,公认的答案是最有帮助的。
仍然认为这种方法适合我最初想做的事情,
所以我会保留它,以防其他人发现它有帮助。

对于最初的问题

“如何检查元素是否包含数组中的所有类”

使用 jQuery,一个简单的解决方案是:

  1. 遍历类数组并将它们连接成一个字符串。
  2. 使用 jQuery 选择该字符串
  3. 只返回匹配的元素

$('.filter-option').on('change', function (event) {
  const activeFilters = $('.filter-option:checked');
  let classString = "";
  
  if (activeFilters.length === 0) {
    $('.product').show();
  } else {
    $('.product').hide();
    activeFilters.each((index, filter) => {
      classString += "." + filter.id;
    });
    $(classString).show();
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="filter-box">
    <h3>Size</h3>
    <input type="checkbox" class="filter-option" id="size-s" name="size-s">
    <label for="size-s" class="filter-option-label">Small</label>
    <input type="checkbox" class="filter-option" id="size-m" name="size-m">
    <label for="size-m" class="filter-option-label">Medium</label>
    <input type="checkbox" class="filter-option" id="size-l" name="size-l">
    <label for="size-l" class="filter-option-label">Large</label>
    <h3>Colour</h3>
    <input type="checkbox" class="filter-option" id="color-white" name="color-white">
    <label for="color-white" class="filter-option-label">White</label>
    <input type="checkbox" class="filter-option" id="color-red" name="color-red">
    <label for="color-red" class="filter-option-label">Red</label>
    <input type="checkbox" class="filter-option" id="color-blue" name="color-blue">
    <label for="color-blue" class="filter-option-label">Blue</label>
</div>
<ul id="product-list">
    <li class="product color-red size-l">Red Large</li>
    <li class="product color-red size-m">Red Medium</li>
    <li class="product color-red size-s">Red Small</li>
    <li class="product color-blue size-l">Blue Large</li>
    <li class="product color-blue size-m">Blue Medium</li>
    <li class="product color-blue size-s">Blue Small</li>
    <li class="product color-white size-l">White Large</li>
    <li class="product color-white size-m">White Medium</li>
    <li class="product color-white size-s">White Small</li>
</ul>

小提琴:https://jsfiddle.net/Chazlol/3zuaey0x/1/

【讨论】:

    【解决方案3】:

    使用&lt;input type "radio"&gt; 元素“单选按钮”而不是inpout type="checkbox"&gt; 元素可能会更好地为您服务,因为它们只允许检查同名元素之一。使元素可见或不可见的脚本很简单:

    const ul=document.querySelector('#product-list');
    document.querySelector('.filter-box').onchange=ev=>{
      let siz=document.querySelector('[name=size]:checked');
      let col=document.querySelector('[name=colour]:checked');
      [...ul.children].filter(li=>
         li.style.display= siz&&li.classList.contains(siz.value)
                        && col&&li.classList.contains(col.value) ? 'block': 'none' 
      );
    }
    <div class="filter-box">
        <h3>Size</h3>
        <label><input type="radio" name="size" value="size-s">small</label>
        <label><input type="radio" name="size" value="size-m">medium</label>
        <label><input type="radio" name="size" value="size-l">large</label>
        <h3>Colour</h3>
        <label><input type="radio" name="colour" value="color-white">white</label>
        <label><input type="radio" name="colour" value="color-red">red</label>
        <label><input type="radio" name="colour" value="color-blue">blue</label>
    </div>
    
    <ul id="product-list">
        <li class="product color-red size-l">Red Large</li>
        <li class="product color-red size-m">Red Medium</li>
        <li class="product color-red size-s">Red Small</li>
        <li class="product color-blue size-l">Blue Large</li>
        <li class="product color-blue size-m">Blue Medium</li>
        <li class="product color-blue size-s">Blue Small</li>
        <li class="product color-white size-l">White Large</li>
        <li class="product color-white size-m">White Medium</li>
        <li class="product color-white size-s">White Small</li>
    </ul>

    【讨论】:

      【解决方案4】:

      您可以结合使用Array.prototype.every() 和 JQuery .hasClass()

      const classList = ['a', 'b'];
      
      function checkClassList($el, classList){
        return classList.every((c) => $el.hasClass(c));
      }
      
      console.log(checkClassList($("#id1"), classList))
      console.log(checkClassList($("#id2"), classList))
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <ul id="id1" class="a b"></ul>
      <ul id="id2" class="a"></ul>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-20
        • 1970-01-01
        • 1970-01-01
        • 2019-05-05
        • 2016-10-13
        • 1970-01-01
        相关资源
        最近更新 更多