必须用<ul class="cart-items">包裹商品项,每项为<li role="group">并设唯一data-item-id;数量用<input type="number">;结算区须用<form>包裹,总价用<span id="total-price">,优惠用<dl>结构,全选/单选依赖统一name属性。

用 <ul> + <li> 做商品列表,别用 <div> 堆砌
语义错误是后期 JS 绑定失败的头号原因。用 <ul class="cart-items"> 包裹所有商品项,每个商品必须是 <li role="group">,而不是一堆 <div class="item">。前者让屏幕阅读器能识别为“一组可操作条目”,JS 也能用 document.querySelectorAll('.cart-items > li') 精准遍历,后者容易因 class 名重复或嵌套过深导致 querySelector 拿错节点。
常见错误现象:document.querySelector('.cart-item') 返回 null,但 HTML 里明明有对应 class —— 很可能是因为该 class 出现在多层嵌套 <div> 里,而你漏写了父级限定;或者多个商品块用了相同 ID。
- 每个
<li>必须带唯一data-item-id,如data-item-id="prod-2026",JS 后续增删改全靠它定位,别依赖 textContent 或 index - 商品图片必须带
alt,哪怕只是“商品缩略图”,否则无障碍测试直接不通过 - 数量输入框强制用
<input type="number" min="1" value="1">,省去 JS 初次校验负数/空值的逻辑
结算区必须用 <form> 包裹,总价用 <span id="total-price">
看似只是个显示区域,实则影响回车提交、移动端键盘行为和 JS 更新效率。不用 <form>,用户在数量框输完按回车,页面不会触发任何动作;移动端键盘右下角“完成”键失效,用户得手动点屏幕外收起键盘。
总价不能写成 <div class="total">¥128.00</div>,而要明确给 id:<span id="total-price">¥0.00</span>。JS 更新时用 document.getElementById('total-price').textContent = '¥' + total.toFixed(2),比反复 querySelector 找 class 快且稳定。
立即学习“前端免费学习笔记(深入)”;
- 优惠信息建议用
<dl><dt>满减</dt><dd id="discount-amount">-¥10.00</dd></dl>,方便 JS 单独替换<dd>内容而不影响结构 -
<button type="submit">必须放在<form>内,哪怕后端还没接入,否则无法响应回车和空格键 - 不要把总价塞进
<h3>或<p>里再加 class,ID 是最小成本定位方式
勾选逻辑依赖 name 属性,不是 class 或 data-*
全选/单选联动失效,90% 是因为 checkbox 的 name 不统一。所有商品行的勾选框必须共用一个 name,比如 name="cart-item-check",全选框则用 name="check-all"。JS 判断是否全选时,靠的是 document.querySelectorAll('input[name="cart-item-check"]:checked').length,而不是靠 class 名找“被选中”的元素。
容易踩的坑:用 jQuery 的 $('input.checked') 去筛选——这个 class 是 JS 动态加的,DOM 初始化时并不存在;或者用 data-checked="true" 控制状态,结果忘了同步原生 checked 属性,导致表单 submit 时 checkbox 值丢失。
- 全选框本身也要有
name,但值不同(如name="check-all"),避免和商品项混在一起被当成同一组 - 不要用
onclick="toggleCheck()"写内联事件,所有监听统一用addEventListener绑定到父容器,委托处理 - 勾选状态变更后,立刻更新对应商品行的
aria-checked属性,兼顾可访问性
表格布局适合固定字段,但响应式差
如果商品字段固定(名称、单价、数量、小计、操作),<table> 结构清晰、语义强、打印友好,且天然支持 <thead>/<tbody> 分离。但一旦加“规格”“赠品”“库存状态”等动态列,<tr> 对齐会崩,移动端横向滚动难控制。
更灵活的做法是用 <ul> + Flex 布局模拟表格视觉效果:每项 <li> 设 display: flex,子元素按比例设 flex: 0 0 25% 等。这样字段增减不影响整体结构,也更容易做折叠/展开交互。
- 用
<table>时,<tbody>必须为空,所有商品由 JS 动态insertAdjacentHTML插入,否则初始渲染和 JS 渲染逻辑割裂 - 表格内禁止嵌套
<div>做布局,会破坏cellspacing和colspan行为 - 移动端若坚持用表格,至少给
<table>加class="responsive-table"并配 media query 强制display: block,让每行变成堆叠块
data-item-id 的唯一性和 <form> 的包裹完整性——它们不报错,但会让调试时间翻倍。



















