纯HTML表格需重构为语义化结构:必须显式使用thead/tbody/tfoot,th须设scope属性,废弃table内联属性改用CSS控制,购物车input需绑定data-id而非索引,总价应缓存计算。

纯 HTML 表格在商城页面中容易变成维护黑洞——样式难统一、响应式失效、语义缺失导致无障碍失败,甚至影响后续 JS 交互逻辑。重构不是重写,而是用现代语义结构 + CSS 控制力 + 可访问性锚点,把表格从“能看”变成“可读、可操作、可扩展”。
为什么 table 必须显式拆分 thead/tbody/tfoot
很多商城购物车或商品参数表直接用 table 套 tr,省掉 thead 和 tbody。这会导致三个实际问题:
- 打印时表头不会自动重复到每页,用户打印订单可能漏看列名
- 屏幕阅读器无法区分“这是标题行”还是“这是数据行”,
th单独存在但无上下文,scope属性失效 - JS 想固定表头或滚动主体时,没有语义容器就只能靠 class 模拟,一改 class 全崩
正确做法是:哪怕只有一行表头,也必须包裹进 thead;所有商品行必须进 tbody;总价行放进 tfoot(即使视觉上它在底部)。tfoot 在 DOM 中可放在 tbody 前,浏览器仍会渲染到底部,且支持打印复现。
th 的 scope 属性不能省,尤其在多维表格里
商城常见“规格对比表”(如手机参数横向比对),会出现跨行/跨列表头。此时仅靠视觉加粗和位置推断行列关系,对辅助技术完全不可靠。
-
明确告诉屏幕阅读器:“这一列所有屏幕尺寸 td都属于‘屏幕尺寸’这个维度” -
则标注整行为该机型数据iPhone 15 - 如果用了
rowspan或colspan,scope必须同步适配,否则辅助技术会跳过合并单元格后的逻辑映射
不设 scope 的 th,等于没设——浏览器和读屏软件都当普通文本处理。
用 CSS 替代所有废弃的 table 属性
像 border="1"、cellspacing="0"、cellpadding="8" 这类属性,在现代项目里继续用,等于主动放弃样式控制权和响应式能力。
-
border→ 改用border-collapse: collapse+ 单元格border,可单独控制某列边框 -
cellspacing→ 对应border-spacing: 0,但更推荐直接设border-collapse,避免双线bug -
cellpadding→ 全部转为td, th { padding: 0.5em 0.75em },单位用em或rem才能随字体缩放 -
align、valign等已废弃,必须用text-align/vertical-align
保留内联属性的后果:CSS 覆盖成本高、无法用媒体查询动态调整、DevTools 调试时样式来源混乱。
购物车表格的 input[type="number"] 必须带 data-id 而非索引
重构购物车表格时,最常踩的坑是用 Array.from(trs).indexOf(row) 当商品唯一标识。一旦用户删了一行,后续所有索引偏移,小计计算全错。
- 每个数量输入框必须有
data-id="prod-1024"这类稳定 ID,与后端商品 ID 对齐 - 监听事件用
input(实时)+change(失焦补全),别只用后者,否则滚轮调数量不触发 -
row.remove()是安全删除的唯一方式,清空innerHTML会销毁已绑定的事件监听器 - 总价汇总不要遍历 DOM 读文本,而是维护一个 JS 对象缓存
{ "prod-1024": { qty: 2, price: 299 } },再算总和
表格 DOM 结构越干净,JS 逻辑就越不容易被视觉改动牵连——这才是重构真正的终点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











