订单表格应将<form>置于<table>外层,每行商品用<tr>,数量输入框用<input type="number" min="1" step="1">并命名如name="items0",小计通过监听input事件实时计算,提交前校验数量有效性。

订单表格结构用 <table> 搭建,但别嵌套表单
HTML 表格本身不处理数据,只是展示容器。把 <form> 放在 <table> 外层,而不是每个 <tr> 里套一个表单——否则提交时只能拿到最后一行的值。每一行商品用 <tr>,商品名、单价、数量输入框、小计用 <td> 拆开,数量用 <input type="number">,加 min="1" 和 step="1" 防负数和小数。
name 属性必须带唯一标识,否则后端收不到多行数据
如果所有数量框都写 name="quantity",PHP 或 Node.js 默认只取最后一个值。正确做法是用数组式命名:name="items[0][quantity]"、name="items[1][quantity]",或语义化命名如 name="quantity[prod-101]"。对应商品 ID 或索引,方便后端遍历解析。别依赖 id——它只用于 JS 或 CSS,不参与表单提交。
小计实时计算得靠 JS,input 事件比 change 更及时
用户还没离开输入框就该更新小计,所以监听 input 事件,不是 change。每行绑定独立逻辑:取当前行的单价单元格文本(parseFloat(td[1].textContent))、取数量输入框的 valueAsNumber,相乘后写进对应的小计 <td>。注意空值和非数字要判空,否则算出 NaN。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
document.querySelectorAll('input[name^="quantity"]').forEach(inp => {
inp.addEventListener('input', function() {
const row = this.closest('tr');
const price = parseFloat(row.cells[1].textContent) || 0;
const qty = this.valueAsNumber || 0;
row.cells[3].textContent = (price * qty).toFixed(2);
});
});提交前校验数量是否为空或为 0,避免后端白忙活
用户可能清空输入框或输 0,但 type="number" 清空后 valueAsNumber 是 NaN,不是 0。校验时用 !inp.valueAsNumber && inp.value !== '' 判断无效输入。发现异常就 inp.focus() 并提示,event.preventDefault() 拦住提交。别只靠前端校验,后端仍要二次检查,但前端拦截能立刻反馈。
立即学习“前端免费学习笔记(深入)”;
容易漏掉的是 disabled 输入框——比如库存为 0 时禁用,但若没同步设 name 属性,它就不会随表单提交,后端就收不到这条记录的意图。需要保留 name,仅用 disabled 控制编辑,再靠 hidden input 传状态。


















