我需要将过滤器从单复选框选中结果更改为 Javascript 中的多复选框选中结果

问题描述 投票:0回答:1

我有一个过滤器,使用输入

type=checkbox
html 标签在我的内容 div 上运行。情况是,如果我选择颜色为red的复选框,它只显示包含红色属性的内容,与purpleblue相同。

但是,当我选择多个复选框时,我根本没有得到任何结果,而不是获取所有选定复选框的结果。

class Object {
  constructor(color, shape, price) {
    this.color = color;
    this.shape = shape;
    this.price = price;
  }
}
const objects = [
  object1 = new Object("purple", "square", "$0"),
  object2 = new Object("purple", "circle", "$20"),
  object3 = new Object("red", "square", "$40"),
  object4 = new Object("red", "circle", "$0"),
  object5 = new Object("blue", "square", "$20"),
  object6 = new Object("blue", "circle", "$40"),
  object7 = new Object("purple", "square", "$60"),
  object8 = new Object("purple", "circle", "$80"),
  object9 = new Object("red", "square", "$100"),
  object10 = new Object("red", "circle", "$60"),
  object11 = new Object("blue", "square", "$80"),
  object12 = new Object("blue", "circle", "$100")
];

let text = "";
objects.forEach(objectLoop);
document.getElementById("content").innerHTML = text;

function objectLoop(objects) {
  text += '<p class="object ' + objects.shape + ' ' + objects.color + '">' + objects.price + '</p>';
}

// This is the filter
function change() {
  let results = Array.from(document.querySelectorAll(".content > p"));
  results.forEach(function(result) {
    result.style.display = "none";
  });

  Array.from(document.querySelectorAll(".filters input[rel]:checked"), function(input) {
    const attrib = input.getAttribute("rel");
    results = results.filter(function(result) {
      return result.classList.contains(attrib);
    });
  });

  results.forEach(function(result) {
    result.style.display = "block";
  });
}
change();
<main class="flex">
  <div class="filters">
    <div class="head">
      <h2>Filters</h2>
    </div>
    <div class="content">
      <h3>Color:</h3>
      <div class="group flex">
        <label for="">Red:</label>
        <input type="checkbox" rel="red" onchange="change()">
      </div>
      <div class="group flex">
        <label for="">Purple:</label>
        <input type="checkbox" rel="purple" onchange="change()">
      </div>
      <div class="group flex">
        <label for="">Blue:</label>
        <input type="checkbox" rel="blue" onchange="change()">
      </div>
      <button>Reset filters</button>
    </div>
    <div class="foot"></div>
  </div>
  <div class="objects">
    <div class="head">
      <h2>Objects</h2>
    </div>
    <div class="content flex" id="content"></div>
    <div class="foot"></div>
  </div>
</main>

javascript filter checkbox
1个回答
0
投票

在您的代码中,当选择多个复选框时,您的过滤逻辑似乎不正确。您正在为每个选中的复选框单独过滤结果数组,这会导致结果的交集,这意味着您只会获得满足所有选定复选框的项目,这可能不是您想要的。

要解决此问题,您需要调整过滤逻辑以保留满足任何选定复选框的项目,而不是全部

class Object {
  constructor(color, shape, price) {
    this.color = color;
    this.shape = shape;
    this.price = price;
  }
}
const objects = [
  object1 = new Object("purple", "square", "$0"),
  object2 = new Object("purple", "circle", "$20"),
  object3 = new Object("red", "square", "$40"),
  object4 = new Object("red", "circle", "$0"),
  object5 = new Object("blue", "square", "$20"),
  object6 = new Object("blue", "circle", "$40"),
  object7 = new Object("purple", "square", "$60"),
  object8 = new Object("purple", "circle", "$80"),
  object9 = new Object("red", "square", "$100"),
  object10 = new Object("red", "circle", "$60"),
  object11 = new Object("blue", "square", "$80"),
  object12 = new Object("blue", "circle", "$100")
];

let text = "";
objects.forEach(objectLoop);
document.getElementById("content").innerHTML = text;

function objectLoop(objects) {
  text += '<p class="object ' + objects.shape + ' ' + objects.color + '">' + objects.price + '</p>';
}

// This is the filter
function change() {
  let results = Array.from(document.querySelectorAll(".content > p"));
  results.forEach(function(result) {
    result.style.display = "none";
  });

  const checkedBoxes = Array.from(document.querySelectorAll(".filters input[rel]:checked"))
    .map(input => input.getAttribute("rel"));

  if (checkedBoxes.length === 0) {
    // If no checkboxes are checked, display all results
    results.forEach(function(result) {
      result.style.display = "block";
    });
  } else {
    results.forEach(function(result) {
      const classes = result.className.split(" ");
      if (checkedBoxes.some(box => classes.includes(box))) {
        result.style.display = "block";
      }
    });
  }
}
change();
<main class="flex">
  <div class="filters">
    <div class="head">
      <h2>Filters</h2>
    </div>
    <div class="content">
      <h3>Color:</h3>
      <div class="group flex">
        <label for="">Red:</label>
        <input type="checkbox" rel="red" onchange="change()">
      </div>
      <div class="group flex">
        <label for="">Purple:</label>
        <input type="checkbox" rel="purple" onchange="change()">
      </div>
      <div class="group flex">
        <label for="">Blue:</label>
        <input type="checkbox" rel="blue" onchange="change()">
      </div>
      <button>Reset filters</button>
    </div>
    <div class="foot"></div>
  </div>
  <div class="objects">
    <div class="head">
      <h2>Objects</h2>
    </div>
    <div class="content flex" id="content"></div>
    <div class="foot"></div>
  </div>
</main>

© www.soinside.com 2019 - 2024. All rights reserved.