最稳妥方案是语义化form+checkbox/range搭配JS实时过滤:商品数据从JSON脚本提取,用Array.filter()多条件筛选(空条件视为不限),DOM更新采用DocumentFragment,兼顾无障碍、SEO与性能。

用 form + input[type="checkbox"] 搭配 JS 实时过滤最稳妥
纯 HTML 无法动态筛选,必须配合 JavaScript;但结构要靠语义化表单打底,否则筛选逻辑难维护、无障碍支持差。推荐把每个筛选项(如品牌、价格区间、分类)做成独立的 form 区块或统一 form 下的多组 input[type="checkbox"] 或 input[type="range"]。
常见错误是直接用 div + onclick 模拟勾选,结果筛选状态无法被 JS 批量读取、重置困难、键盘操作不支持。
- 所有筛选控件必须有
name属性,相同筛选维度(如“品牌”)用同一name,例如name="brand" - 每个
input的value应为后端可识别的标识符(如value="apple"),别用中文文本 - 价格区间用
input[type="range"]时,需同步显示数值,并绑定两个隐藏input存 min/max 值,方便 JS 读取
Array.filter() 是核心,但得先统一商品数据结构
JS 筛选的前提是商品列表是 JS 可访问的数组对象,不是纯 HTML li 标签堆砌。如果数据来自后端渲染,建议在页面加载时用 JSON.parse() 从 script[type="application/json"] 中提取原始数据,而不是解析 DOM。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
例如:
<script type="application/json" id="products-data">
[{"id":1,"name":"iPhone","brand":"apple","price":5999,"category":"phone"}]
</script>
- 筛选前先用
document.querySelectorAll('input[name="brand"]:checked')获取当前选中的值数组 - 多条件是「且」关系,所以每个条件都要单独判断:商品的
brand是否在选中数组里、price是否落在区间内 - 注意空条件:如果某组 checkbox 全未勾选,该条件应视为“不限”,不能直接用
includes()导致全过滤掉
DOM 更新别用 innerHTML = '' 拼接,用 DocumentFragment 更稳
每次筛选都重新生成整个商品列表 HTML 字符串再赋给 innerHTML,容易触发 XSS(尤其商品名含 )、丢失已绑定事件、破坏输入焦点。更安全的做法是创建 <code>DocumentFragment,逐个 append() 新节点,最后一次性替换容器内容。
立即学习“前端免费学习笔记(深入)”;
- 避免在循环里反复操作 DOM(如对每个商品调用
appendChild),先建好 fragment 再 append 一次 - 保留原商品 DOM 的
data-id或其他属性,方便后续点击跳转或加入购物车时精准识别 - 如果商品数超 200 条,考虑加节流(
setTimeout防连点)或骨架屏过渡,否则用户会感知卡顿
移动端 click 延迟和 checkbox 样式覆盖是高频坑
iOS Safari 对非可点击元素的 click 有 300ms 延迟,而原生 checkbox 默认样式丑且难控制尺寸。直接给 label 加 cursor: pointer 不够,得确保点击区域足够大并禁用延迟。
- 给外层
label加ontouchstart=""(空属性)可消除 iOS click 延迟 - 隐藏原生
input(position: absolute; opacity: 0),用label::before画自定义勾选框,通过input:checked + label::before控制状态 - 别用
change事件监听 checkbox —— 它不响应通过 JS 设置checked的变化;统一用input事件,兼容手动勾选和脚本触发


















