自动编号功能对动态新增表格行不生效的问题排查
问题根因
- 原代码在页面初始化执行
document.querySelectorAll(".form-control")时,会把当时页面上存在的匹配节点保存为一个固定的静态集合,这个集合是生成时刻的DOM快照,后续通过JS动态插入的新行元素,哪怕和初始元素使用完全相同的form-control类名,也完全不会被纳入这个集合。因此绑定在集合上的遍历赋值逻辑、事件监听都无法触达新元素。 - 原代码把键盘快捷键事件直接绑定在集合里的第一个元素上,没有使用事件委托机制,动态新增的同类型元素自然无法继承事件监听逻辑。
- 原代码存在两处HTML结构错误:一是在
<tbody>内直接嵌套<div>标签,不符合表格标签的嵌套规范,容易引发DOM解析异常;二是拼接新增行HTML字符串时,每一段末尾多写了一个闭合双引号,会破坏生成的节点结构。
修复方案
- 使用事件委托替换原有的直接元素绑定逻辑:把键盘快捷键的监听事件绑定在不会动态变化的表格父容器上,让所有当前存在、以及未来动态新增的匹配类名的元素,都能被事件捕获。
- 调整自动编号的赋值逻辑:触发快捷键时,实时从当前DOM树中查询所有需要赋值的
.form-control元素,不再使用页面初始加载时缓存的旧节点集合。 - 修正HTML结构错误:移除
<tbody>内不合法的<div>嵌套,删掉拼接新增行字符串时多余的双引号。
// 修复后的自动编号逻辑(使用事件委托) const tableDom = document.querySelector("#applicanttable"); // 把事件绑在静态存在的表格容器上,自动捕获所有动态行的事件 tableDom.addEventListener("keyup", e => { // 仅匹配form-control输入框的快捷键触发 if (!e.target.classList.contains("form-control")) return; let startValue = parseInt(e.target.value); if (isNaN(startValue)) return; if ((e.ctrlKey || e.metaKey) && (e.keyCode == 13 || e.keyCode == 10)) { // 触发时实时查询所有当前存在的form-control元素,不再用旧的缓存集合 const allInputs = document.querySelectorAll("#applicanttable .form-control"); allInputs.forEach((inp, index) => { if (index !== 0) { // 跳过第一个作为起始值的输入框 inp.value = ++startValue; } }) } }) // 修复后的新增行逻辑(修正字符串拼接错误) $("#addrow").on('click', function() { let rowIndex = $('.auto_num').length + 1; let rowIndexx = $('.auto_num').length + 1; // 删掉原来每段字符串末尾多余的双引号 var newRow = '<tr><td><input class="auto_num" type="text" value="' + rowIndexx + '" /></td>' + '<td><input name="lightBand' + rowIndex + '" value="" class="form-control" type="number" readonly /></td>' + '<td><input id="weight' + rowIndex + '" name="weight' + rowIndex + '" type="number" /></td>' + '<td><input id="wingBand' + rowIndex + '" name="wingBand' + rowIndex + '" type="number" /></td>' + '<td><input type="button" class="removerow" id="removerow' + rowIndex + '" name="removerow' + rowIndex + '" value="Remove"/></td>'; $("#applicanttable > tbody > tr:last").after(newRow); });
注意:同一页面不要给多个元素设置相同的
id="auto"属性,动态新增的行里的输入框重复设置同一个id会引发DOM选择异常,建议把动态行里重复的id属性移除,仅通过类名、name属性定位元素即可。
内容的提问来源于stack exchange,提问作者Ulquiorra Schiffer
相关产品推荐
相关产品推荐

