本文介绍如何将为每行商品单独发起 ajax 请求的冗余写法,重构为仅用一个通用事件监听 + 动态 id 绑定的优雅方案,大幅提升代码可维护性与性能。
在实际开发中,当表单包含大量动态行(如 50+ 行商品录入),若为每一行(如 productCode_1、productCode_2…productCode_50)单独绑定 change 事件并调用独立的 AJAX 函数(如 getDataFromServer1()、getDataFromServer2()),不仅代码重复度高、难以维护,还极易因遗漏或命名错误导致功能异常。
核心优化思路:统一事件委托 + 动态上下文识别
我们不再为每个输入框写独立事件,而是利用 事件委托(Event Delegation),为所有商品编码输入框统一添加 .product-code 类,并通过 data-id 属性标记其所属行号。JavaScript 通过 $(this).attr('data-id') 动态获取当前操作的行索引,再精准填充对应行的其他字段。
✅ 优化后的 HTML 关键改动:
✅ 对应的 JavaScript 重构(使用 jQuery 事件委托):
jQuery(document).on('change', '.product-code', function() {
const $this = $(this);
const PID = $this.val().trim();
const itemId = $this.data('id'); // 安全获取整数行号
if (!PID) return; // 空值不触发请求
getDataFromServer(PID, itemId);
// 自动聚焦下一行(防越界)
const nextId = itemId + 1;
if (nextId <= 50) {
$('#productCode_' + nextId).focus();
}
});
function getDataFromServer(PID, itemId) {
$.ajax({
type: "POST",
url: "response.php",
data: { pro_id: PID },
dataType: "json", // 推荐显式声明,避免手动 parse
success: function(response) {
// 假设 response 是标准 JSON 对象(无需 JSON.parse)
$(`#productName_${itemId}`).val(response.pro_name || '');
$(`#productOnHand_${itemId}`).val(response.pro_quantity || 0);
$(`#price_${itemId}`).val(response.pro_price || 0);
$(`#quantity_${itemId}`).val(1); // 默认数量设为 1
},
error: function(xhr, status, error) {
console.warn(`第 ${itemId} 行加载失败:`, error);
alert(`无法加载商品信息,请检查编码是否正确。`);
}
});
}? 关键优势说明:
⚠️ 注意事项:
通过这一重构,你将告别“复制粘贴式 AJAX”,迈出迈向模块化、可维护前端代码的关键一步。