You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于多复选框值筛选多属性产品的前端实现疑问

多值Data属性的产品筛选实现(纯前端)

我想用JavaScript做一个产品对比页面,页面有多组复选框,用户选颜色、尺寸、供电方式这些条件后,只显示符合条件的产品。产品元素的data属性是多值的(比如data-color="red white blue"),之前找到过单值属性的筛选示例,但多值的搞不定,想问这个功能是不是必须后端来做?

示例HTML代码

<h4 class="heading-primary">color</h4>
<ul>
  <label><input type="checkbox" data-filter-type="color" value="red" /> red</label><br>
  <label><input type="checkbox" data-filter-type="color" value="white" /> white</label><br>
  <label><input type="checkbox" data-filter-type="color" value="blue" /> blue</label><br>
  <label><input type="checkbox" data-filter-type="color" value="orange" /> orange</label><br>
  <label><input type="checkbox" data-filter-type="color" value="green" /> green</label><br/>
  <label><input type="checkbox" data-filter-type="color" value="purple" /> purple</label><br/>
</ul>
<h4 class="heading-primary">size</h4>
<ul>
  <label><input type="checkbox" data-filter-type="size" value="small" /> small</label><br>
  <label><input type="checkbox" data-filter-type="size" value="medium" /> medium</label><br>
  <label><input type="checkbox" data-filter-type="size" value="large" /> large</label><br/>
  <label><input type="checkbox" data-filter-type="size" value="xl" />xl</label><br/>
</ul>
<h4 class="heading-primary">External power</h4>
<ul>
  <label><input type="checkbox" data-filter-type="power" value="battery" /> Battery</label><br>
  <label><input type="checkbox" data-filter-type="power" value="solar" /> Solar</label><br>
  <label><input type="checkbox" data-filter-type="power" value="inductive" /> Inductive</label><br>
</ul>

<h4 class="heading-primary">casing </h4>
<ul>
  <label><input type="checkbox" data-filter-type="casing" value="car" />
   Car </label><br>
  <label><input type="checkbox" data-filter-type="casing" value="key" /> Key fob</label><br>
  <label><input type="checkbox" data-filter-type="casing" value="oem" /> Oem</label><br>
</ul>

<h4 class="heading-primary">Sensors</h4>
<ul>
  <label><input type="checkbox" data-filter-type="sensor" value="acceleration" /> Acceleration</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="Temperature" /> Temperature</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="Humidity" /> Humidity</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="airquality" /> Air quality</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="magneto" /> Compass / Magneto</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="audio" /> Audio</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="barometer" /> Barometer / Altitude</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="distance" /> Distance</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="pir" />  Movement (PIR)</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="co2" /> Co2</label><br>
  <label><input type="checkbox" data-filter-type="sensor" value="light" />  Light sensor</label><br>
</ul>

<h4 class="heading-primary">External connectors</h4>
<ul>
  <label><input type="checkbox" data-filter-type="extconnector" value="yes" /> Yes</label><br>
  <label><input type="checkbox" data-filter-type="extconnector" value="no" /> No</label><br>
</ul>

<div class="products">
  <div class="productItem" data-color="red white blue orange purple green" data-size="small medium large" data-power="battery" data-extconnector="yes">Module 178<br></div>
  <div class="productItem" data-color="white" data-size="small medium large" data-power="inductive battery" data-extconnector="yes">Module R9B3<br></div>
  <div class="productItem" data-color="white" data-size="small medium large" data-power="powerC" data-extconnector="yes">Module 186<br></div>
  <div class="productItem" data-color="orange" data-size="small medium large" data-power="inductive battery" data-extconnector="no">Module 187/R9A11<br></div>
  <div class="productItem" data-color="orange" data-size="small medium large" data-power="inductive battery" data-extconnector="no">Module 3001<br></div>
  <div class="productItem" data-color="orange" data-size="medium" data-power="inductive battery solar" data-extconnector="no">Module 231<br></div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="inductive battery" data-extconnector="no"> Module medium </div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 2001</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 2011</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 2016</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 2206</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 2207</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 2208</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no"> Module 1025</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no">Module 206</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no">Module 3101</div>
  <div class="productItem" data-color="purple" data-size="medium" data-power="battery" data-extconnector="no">Module power</div>
</div>

纯前端实现方案

完全不用后端,纯JS就能搞定。核心思路是:收集用户选中的所有筛选条件,按类型分组,然后逐个检查产品是否满足所有选中的分组条件。

具体代码实现

// 获取所有复选框和产品元素
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
const products = document.querySelectorAll('.productItem');

// 给每个复选框绑定筛选事件
checkboxes.forEach(checkbox => {
  checkbox.addEventListener('change', filterProducts);
});

function filterProducts() {
  // 1. 收集选中的筛选条件,按类型分组
  const filters = {};
  checkboxes.forEach(checkbox => {
    if (checkbox.checked) {
      const type = checkbox.dataset.filterType;
      if (!filters[type]) {
        filters[type] = [];
      }
      filters[type].push(checkbox.value.toLowerCase()); // 转小写避免大小写问题
    }
  });

  // 2. 遍历每个产品,检查是否符合条件
  products.forEach(product => {
    let isMatch = true;

    // 遍历每个筛选分组
    for (const [type, values] of Object.entries(filters)) {
      // 获取产品对应的多值属性,转成小写数组
      const productValues = product.dataset[type]?.toLowerCase().split(' ') || [];
      // 检查产品是否有至少一个值在当前筛选分组的选中值里
      const hasMatch = values.some(value => productValues.includes(value));
      if (!hasMatch) {
        isMatch = false;
        break; // 只要一个分组不满足,直接跳出
      }
    }

    // 3. 根据匹配结果显示/隐藏产品
    product.style.display = isMatch ? 'block' : 'none';
  });
}

关键说明

  • 分组收集筛选条件:把同一类型(比如color)的选中值放到一个数组里,方便后续检查。
  • 多值属性处理:用split(' ')把产品的多值data属性拆成数组,转小写是为了避免大小写匹配问题(比如筛选值是"red",产品属性是"Red")。
  • 条件匹配逻辑:
    • 如果某个筛选类型没有选中任何选项,就跳过该类型的检查(相当于不对该类型做限制)。
    • 对于有选中项的类型,产品必须至少包含一个选中值才算符合该类型的条件。
    • 只有所有有选中项的类型都符合,产品才会显示。

额外优化建议

  • 给产品初始添加display: block样式,确保默认显示所有产品。
  • 如果要支持“全选/全不选”功能,可以给每个筛选组加按钮,批量控制复选框状态。
  • 产品数量特别多时,用Debounce函数避免用户快速点击复选框时频繁触发筛选。

内容的提问来源于stack exchange,提问作者dennis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:27:33