使用原生 <dialog> 实现菜品规格多选弹窗:点击触发、动态渲染JSON规格列表、回传选中ID与价格并更新预览和总价,提交时校验并组装标准JSON订单数据。

用 HTML + JavaScript 实现菜品规格多选弹窗,核心是「点击触发、动态渲染、回传选中值」,不需要框架也能做到简洁可靠。
弹窗结构用原生 dialog 最轻量
HTML <dialog> 标签原生支持模态弹窗,语义清晰、无需额外 CSS 遮罩层:
- 在页面底部放一个
<dialog id="specDialog">,里面放规格复选框(<input type="checkbox">)和「确认」「取消」按钮 - 用
dialog.showModal()触发显示,dialog.close()关闭 - 注意添加
autofocus到第一个 checkbox 或确认按钮,提升键盘可访问性
点击菜品时动态加载对应规格
每个菜品按钮/卡片绑定 data-specs 属性,存 JSON 字符串(如 '[{"id":"s1","name":"大份","price":5},{"id":"s2","name":"加辣","price":2}]'):
- 点击时解析该属性,清空弹窗内原有选项,用 JS 动态生成 checkbox 列表
- 每个 checkbox 的
value设为规格 ID,data-price存价格,data-name存名称,方便后续组合使用 - 避免把所有规格一次性渲染到 DOM,按需加载更干净
选中后回填到订单行并更新价格
用户点「确认」时,收集所有勾选的 checkbox,并同步更新当前菜品的展示信息:
立即学习“前端免费学习笔记(深入)”;
- 拼接选中规格名称(如「大份、加辣」),写入菜品行旁的
<small class="specs-preview"> - 累加选中规格价格,更新该菜品的总价(原价 + 规格溢价)
- 把完整选中数据(菜品 ID + 规格 ID 数组 + 实际金额)存在该行的
data-order-item中,供提交时统一读取
提交前校验与数据组装
表单提交时,不直接读 DOM,而是遍历每道已选菜品的 data-order-item:
- 确保至少选了一个主菜品(非空)
- 对每道菜,检查规格数组是否合法(ID 是否存在、是否重复等)
- 最终组装成标准 JSON,例如:
{ "items": [{ "dishId": "d101", "specs": ["s1","s2"], "total": 32 }] }



















