
本文介绍如何使用原生 javascript 为商品列表添加动态分组筛选功能,通过 data 属性标记分组、自动生成带复选框的筛选控件,并利用 classlist.toggle 实现无刷新显隐切换。
本文介绍如何使用原生 javascript 为商品列表添加动态分组筛选功能,通过 data 属性标记分组、自动生成带复选框的筛选控件,并利用 classlist.toggle 实现无刷新显隐切换。
在构建交互式商品展示页面时,常需让用户按类别(如“warme dranken”、“snacks”)快速筛选内容。与其每次点击都重新渲染 DOM,更高效的做法是:一次性渲染全部商品,并通过 CSS 类控制显隐。以下是完整、可直接运行的实现方案。
✅ 核心思路
- 为每个 <li> 元素添加 data-group 属性,绑定其所属分组;
- 自动提取所有唯一分组名,动态生成带标签的复选框控件;
- 复选框默认勾选(即初始显示全部),点击时切换对应分组商品的 .hide 类;
- 利用 CSS 的 display: none 实现高性能隐藏/显示。
? 完整代码实现
<style>
.hide { display: none; }
#filterControls { margin-bottom: 16px; }
#filterControls label { margin-right: 12px; margin-left: 4px; font-weight: 500; }
</style>
<div id="filterControls"></div>
<ul id="productList"></ul>const products = [
{ name: 'koffie', price: 2.50, group: 'warme dranken' },
{ name: 'thee', price: 2.50, group: 'warme dranken' },
{ name: 'cola', price: 3.50, group: 'koude dranken' },
{ name: 'ice tea', price: 3.50, group: 'koude dranken' },
{ name: 'patat', price: 3.50, group: 'friet' },
{ name: 'patat mayo', price: 3.50, group: 'friet' },
{ name: 'frikandel', price: 3.50, group: 'snacks' },
{ name: 'kroket', price: 3.50, group: 'snacks' }
];
const productList = document.querySelector('#productList');
const filterControls = document.querySelector('#filterControls');
// 步骤 1:渲染商品列表,并挂载 data-group 属性
const addProducts = (array, container) => {
array.forEach(item => {
const li = document.createElement('li');
li.textContent = `${item.name} — €${item.price.toFixed(2)}`;
li.dataset.group = item.group; // 关键:绑定分组标识
container.appendChild(li);
});
};
// 步骤 2:自动生成分组筛选控件(复选框 + 标签)
const addGroupBoxes = (array, container) => {
// 提取唯一分组名(ES6 Set 去重)
const groups = [...new Set(array.map(p => p.group))];
groups.forEach(group => {
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.name = group;
checkbox.checked = true; // 默认显示该组
checkbox.className = 'group-filter';
checkbox.addEventListener('change', onCheckboxToggle);
const label = document.createElement('label');
label.textContent = group;
label.htmlFor = group;
container.append(checkbox, label, document.createTextNode(' ')); // 添加空格分隔
});
};
// 步骤 3:处理复选框切换逻辑
const onCheckboxToggle = (e) => {
const groupName = e.target.name;
const items = document.querySelectorAll(`li[data-group="${groupName}"]`);
items.forEach(el => el.classList.toggle('hide'));
};
// 初始化渲染
addProducts(products, productList);
addGroupBoxes(products, filterControls);⚠️ 注意事项与优化建议
- 性能友好:不依赖 filter() 重建数组或重绘 DOM,仅操作 CSS 类,适用于数百项数据;
- 无障碍友好:<label> 与 htmlFor 正确关联,支持键盘聚焦与空格切换;
- 可扩展性强:如需多选联动(例如“仅显示 snacks + friet”),可改用「全选/反选」逻辑 + 维护一个激活分组 Set;
- 样式隔离建议:若项目使用 CSS-in-JS 或 Shadow DOM,.hide 类应置于全局作用域或注入 <style> 块中;
- 移动端适配:可为复选框容器添加 flex-wrap: wrap 防止换行错位。
该方案兼顾简洁性与实用性,无需框架即可实现专业级筛选体验,是原生 JavaScript 动态内容过滤的经典范式。


















