多层级菜单本身不参与筛选逻辑,必须通过JavaScript将菜单状态映射为筛选参数;推荐用data-path统一标识可筛选项,并纳入FormData统一管理,兼顾语义、性能与可访问性。

多层级菜单本身不参与筛选逻辑,它和多条件筛选是两件事;真要组合使用,必须靠 JavaScript 把菜单的展开/选中状态映射为筛选条件,再统一走 FormData 或 data-* 属性驱动过滤。
为什么不能直接用多级菜单 HTML 结构做筛选
多级菜单(比如嵌套 <ul><li><ul></ul></li></ul> 或 CSS :hover + .sub-1)只负责视觉展开与导航,没有内置「选中→提交参数」的能力。用户点了「手机 > iPhone」,HTML 不会自动把 category=phone&brand=apple 塞进请求里——这一步必须由 JS 显式读取并转化。
常见错误现象:
- 点击二级菜单项后页面无反应或跳转到新页 —— 缺少
event.preventDefault()和后续条件采集逻辑 - 「手机」和「iPhone」被当成两个独立筛选项,实际应合并为一个维度(如
path=phone/iphone) - 菜单用
<div class="menu-item" data-id="123"> 实现,但筛选时却去查 <code>class="active"—— class 是 UI 状态,不是数据状态,容易不同步data-path是连接多级菜单与筛选条件最轻量的方式给每个可筛选的菜单项(尤其是叶子节点)加上
data-path,值为标准化路径字符串,例如data-path="electronics/phone/apple"。这样既保留层级语义,又避免嵌套结构解析开销。使用场景:
- 用户点击「电脑 > 笔记本 > MacBook Pro」,触发
filterByPath('electronics/laptop/apple') - 筛选器需支持「同级多选」:勾选「iPhone」和「Samsung Galaxy」,对应两个
data-path值 - 后端 API 接收
?category_path=electronics/phone/apple&category_path=electronics/phone/samsung,用数组接收
注意点:
- 不要用
data-category+data-subcategory拆分,一来增加 JS 判断复杂度,二来无法表达深度大于 2 的路径 - 路径分隔符统一用
/,避免空格、中文、特殊符号;前端可.replace(/[^a-z0-9/]/gi, '')清洗 - 非叶子节点(如纯容器「手机」)不加
data-path,或设为空字符串,防止误触发筛选
如何用
FormData统一管理菜单筛选 + 表单筛选当页面既有传统表单筛选(价格、评分),又有菜单树形筛选(分类路径),别写两套采集逻辑。把菜单项也做成「不可见但合法」的表单控件:
Wechat Article Html下载将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
JS 中统一处理:
- 菜单点击时,找到对应
<input name="category_path">,el.checked = true,再调用form.dispatchEvent(new Event('change')) - 监听
form.change,用new FormData(form)一次性读出所有条件:getAll('category_path')返回数组,get('price_min')返回字符串 - 提交前检查:若
category_path为空数组,可忽略该字段;若有值,就拼进 URL 或 POST body
性能影响:比遍历 DOM 查
data-path更快,且天然兼容 disabled、required、reset 等表单语义。移动端菜单筛选最容易被忽略的交互细节
在 iOS Safari 或安卓 WebView 中,纯 CSS
:hover失效,click又会触发两次(一次展开、一次选中),导致状态错乱。可靠做法:
- 菜单项统一用
<button type="button"></button>包裹,禁用默认行为 - 一级项点击只展开子菜单(
classList.toggle('open')),二级项点击才触发筛选并关闭整个菜单 - 为每个菜单项加
role="menuitem"和aria-expanded,保证屏幕阅读器能识别当前状态 - 避免在
touchstart里立刻执行筛选——要等touchend后 300ms 再判断是否为点击,否则滑动也会触发
真正难的不是怎么展开二级菜单,而是怎么让「用户以为自己在点导航」的同时,系统准确知道「他在选筛选条件」——这两者之间的映射一旦松动,筛选结果就不可信。
- 用户点击「电脑 > 笔记本 > MacBook Pro」,触发










