【问题标题】:How to make a filter in javascript which filters div by checkboxes如何在javascript中制作一个过滤器,通过复选框过滤div
【发布时间】:2018-01-18 16:29:08
【问题描述】:

我需要通过复选框进行过滤,这将在一个类别中指定两个或多个选项。我的过滤器在每个类别中过滤一个选项。

function change() {
  let results = Array.from(document.querySelectorAll('.result > div'));
  // Hide all results
  results.forEach(function(result) {
    result.style.display = 'none';
  });
  // Filter results to only those that meet ALL requirements:
  Array.from(document.querySelectorAll('.filter input[rel]:checked'), function(input) {
    const attrib = input.getAttribute('rel');
    results = results.filter(function(result) {
      return result.classList.contains(attrib);
    });
  });
  // Show those filtered results:
  results.forEach(function(result) {
    result.style.display = 'block';
  });
}
change();
<div class="filter">
  <h1>Select models</h1>
  <div class="checkbox">
    <label><input type="checkbox" rel="apple" onchange="change()"/>Apple</label>
  </div>
  <div class="checkbox">
    <label><input type="checkbox" rel="samsung" onchange="change()"/>Samsung</label>
  </div>
  <div class="checkbox">
    <label><input type="checkbox" rel="xiaomi" onchange="change()"/>Xiaomi</label>
  </div>
  <h1>Select processors</h1>
  <div class="checkbox">
    <label><input type="checkbox" rel="a9" onchange="change()"/>A9</label>
  </div>
  <div class="checkbox">
    <label><input type="checkbox" rel="a8" onchange="change()"/>A8</label>
  </div>
  <div class="checkbox">
    <label><input type="checkbox" rel="snapdragon" onchange="change()"/>Snapdragon</label>
  </div>
  <div class="checkbox">
    <label><input type="checkbox" rel="exynos" onchange="change()"/>Exynos</label>
  </div>
</div>

<div class="result">
  <div class="apple a9">
    <h1>iPhone 7</h1>
  </div>
  <div class="apple a8">
    <h1>iPhone 6</h1>
  </div>
  <div class="samsung exynos">
    <h1>Samsung s7</h1>
  </div>
  <div class="xiaomi snapdragon">
    <h1>Xiaomi Redmi note 4x</h1>
  </div>
</div>

所以结果我不能同时选择苹果和三星。我只能在每组中选择一个选项。它就像一个单选按钮。但我需要带有多个选项的复选框

【问题讨论】:

  • 您想组合这些过滤器(例如:apple AND snapdragon)还是将它们相乘? (例如:苹果或金鱼草)
  • @zeropublix 我需要有机会在每个组中选择更多选项。例如,如果我选择三星和苹果,结果是什么都没有显示,但需要同时显示苹果和三星。我能解释一下我的问题吗?
  • @Mr.Chingis 如果你选择苹果三星和金鱼草怎么办??结果应该是全部 4 部手机还是没有(因为三星和苹果没有金鱼草)?
  • @sanatsathyan 无。因为选择的产品没有金鱼草处理器。如果我选择苹果三星小米和金鱼草,结果应该只有一部手机小米。因为在选择的手机中,至少有一部手机有金鱼草,所以结果应该是小米
  • @Mr.Chingis 是否有任何答案解决了您的问题?然后将它们标记为请或在我们努力为您提供帮助时表示感谢。

标签: javascript html checkbox


【解决方案1】:

据我了解(通过阅读 cmets)您希望具有以下行为:

  • 模型或处理器复选框在其过滤器组内是“或”相关性。
  • 但是手机必须是任何经过检查的型号并且必须有任何经过检查的处理器。

此代码应该可以解决您的问题/疑问:

function change() {
  var modelCbs = document.querySelectorAll(".models input[type='checkbox']");
  var processorCbs = document.querySelectorAll(".processors input[type='checkbox']");
  var filters = {
    models: getClassOfCheckedCheckboxes(modelCbs),
    processors: getClassOfCheckedCheckboxes(processorCbs)
  };

  filterResults(filters);
}

function getClassOfCheckedCheckboxes(checkboxes) {
  var classes = [];

  if (checkboxes && checkboxes.length > 0) {
    for (var i = 0; i < checkboxes.length; i++) {
      var cb = checkboxes[i];

      if (cb.checked) {
        classes.push(cb.getAttribute("rel"));
      }
    }
  }

  return classes;
}

function filterResults(filters) {
  var rElems = document.querySelectorAll(".result div");
  var hiddenElems = [];

  if (!rElems || rElems.length <= 0) {
    return;
  }

  for (var i = 0; i < rElems.length; i++) {
    var el = rElems[i];

    if (filters.models.length > 0) {
      var isHidden = true;

      for (var j = 0; j < filters.models.length; j++) {
        var filter = filters.models[j];

        if (el.classList.contains(filter)) {
          isHidden = false;
          break;
        }
      }

      if (isHidden) {
        hiddenElems.push(el);
      }
    }

    if (filters.processors.length > 0) {
      var isHidden = true;

      for (var j = 0; j < filters.processors.length; j++) {
        var filter = filters.processors[j];

        if (el.classList.contains(filter)) {
          isHidden = false;
          break;
        }
      }

      if (isHidden) {
        hiddenElems.push(el);
      }
    }
  }

  for (var i = 0; i < rElems.length; i++) {
    rElems[i].style.display = "block";
  }

  if (hiddenElems.length <= 0) {
    return;
  }

  for (var i = 0; i < hiddenElems.length; i++) {
    hiddenElems[i].style.display = "none";
  }
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
</head>

<body>
  <div class="filter">
    <h1>Select models</h1>
    <div class="models">
      <div class="checkbox">
        <label><input type="checkbox" rel="apple" onchange="change();"/>Apple</label>
      </div>
      <div class="checkbox">
        <label><input type="checkbox" rel="samsung" onchange="change();"/>Samsung</label>
      </div>
      <div class="checkbox">
        <label><input type="checkbox" rel="xiaomi" onchange="change();"/>Xiaomi</label>
      </div>
    </div>
    <h1>Select processors</h1>
    <div class="processors">
      <div class="checkbox">
        <label><input type="checkbox" rel="a9" onchange="change();"/>A9</label>
      </div>
      <div class="checkbox">
        <label><input type="checkbox" rel="a8" onchange="change();"/>A8</label>
      </div>
      <div class="checkbox">
        <label><input type="checkbox" rel="snapdragon" onchange="change();"/>Snapdragon</label>
      </div>
      <div class="checkbox">
        <label><input type="checkbox" rel="exynos" onchange="change();"/>Exynos</label>
      </div>
    </div>
  </div>

  <div class="result">
    <div class="apple a9">
      <h1>iPhone 7</h1>
    </div>
    <div class="apple a8">
      <h1>iPhone 6</h1>
    </div>
    <div class="samsung exynos">
      <h1>Samsung s7</h1>
    </div>
    <div class="xiaomi snapdragon">
      <h1>Xiaomi Redmi note 4x</h1>
    </div>
  </div>
</body>

【讨论】:

  • 当 div 产品内部没有 div 时,代码正在运行。例如,&lt;div class="apple a9"&gt;&lt;div class="head"&gt;&lt;h1&gt;HEAD&lt;/h1&gt;&lt;/div&gt;&lt;/div&gt; 在这种情况下代码没有给出结果
  • @Mr.Chingis 当然它不起作用,因为我使用的选择器是 var rElems = document.querySelectorAll(".result div"); 让它像这样工作,你应该给每个第一级 div 一个特定的属性,或者可能使用 @987654325 @ 可能有效(未测试)。
【解决方案2】:

试试这个,或者你可以看到前面的演示:https://jsfiddle.net/xianshenglu/gzs3fr7n/

    <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta content="height=device-width, initial-scale=1.0, maximum-scale=1.0,user-scalable=no" name="viewport">
    <title>Document</title>
    <style>

    </style>
    <!-- <script type="text/javascript" src="http://livejs.com/live.js"></script> -->
    <!-- <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> -->
    <!-- <script src="test2.js"></script> -->
    <script>
    function change() {
        let results = Array.from(document.querySelectorAll('.result > div')),
            modelsChecked = document.querySelectorAll('.filter input.models:checked'),
            processorsChecked = document.querySelectorAll('.filter input.processors:checked');
        // Hide all results
        results.forEach(function(result) {
            result.style.display = 'none';
        });
        // Filter results to only those that meet ALL requirements:        

        filterModelsOrProcessors(modelsChecked);

        if (processorsChecked.length != 0) {
            filterModelsOrProcessors(processorsChecked);
        }

        function filterModelsOrProcessors(modelsOrProcessorsChecked) {
            results = Array.from(modelsOrProcessorsChecked).reduce(function(sum, input) {
                const attrib = input.getAttribute('rel');
                return sum.concat(results.filter(function(result) {
                    return result.classList.contains(attrib);
                }));
            }, []);
        }
        // Show those filtered results:
        results.forEach(function(result) {
            result.style.display = 'block';
        });
    }
    change();
    </script>
</head>

<body>
    <div class="filter">
        <h1>Select models</h1>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="apple" class="models" onchange="change()" />Apple</label>
        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="samsung" class="models" onchange="change()" />Samsung</label>
        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="xiaomi" class="models" onchange="change()" />Xiaomi</label>
        </div>
        <h1>Select processors</h1>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="a9" class="processors" onchange="change()" />A9</label>
        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="a8" class="processors" onchange="change()" />A8</label>
        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="snapdragon" class="processors" onchange="change()" />Snapdragon</label>
        </div>
        <div class="checkbox">
            <label>
                <input type="checkbox" rel="exynos" class="processors" onchange="change()" />Exynos</label>
        </div>
    </div>
    <div class="result">
        <div class="apple a9">
            <h1>iPhone 7</h1>
        </div>
        <div class="apple a8">
            <h1>iPhone 6</h1>
        </div>
        <div class="samsung exynos">
            <h1>Samsung s7</h1>
        </div>
        <div class="xiaomi snapdragon">
            <h1>Xiaomi Redmi note 4x</h1>
        </div>
    </div>
</body>

</html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-12
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多