Bootstrap表单JS添加/移除行功能报错,请求排查问题
问题:Bootstrap表单添加/移除div行功能,移除功能出错
我用Bootstrap在页面中创建了一个表单,希望实现添加和移除由div构建的表格行的功能。以下是对应的HTML和JS代码,但移除功能出现错误,请问哪里出错了?
原HTML代码
<form name="modulo" id="form1"> <br/> <div class="row"> <div class="col-2"> <label for="fld1">Label:</label> </div> <div class="col"> <input type="text" name="fld1"> </div> </div> <div class="row"> <div class="col-2"> <label for="fld2">Label2:</label> </div> <div class="col"> <input type="text" name="fld2"> </div> </div> <div class="row"> <div class="col"> <input type="button" value="Add" onclick="addnewrow()" /> </div> </div> <div class="row"> <div class="col"> </div> </div> <div class="row"> <div class="col"> <input type="text" name="fldA0"> </div> <div class="col"> <input type="text" name="fldB0"> </div> <div class="col"> <input type="text" name="fldC0"> </div> <div class="col"> <input type="text" name="fldD0"> </div> <div class="col"> <input type="button" disabled="disabled" value="remove" /> </div> </div> </form>
原JS代码
var num=1; function addnewrow(){ if(document.createElement && document.getElementById && document.getElementsByTagName) { var oTr=document.createElement("div"); var oTd1=document.createElement("div"); var oTd2=document.createElement("div"); var oTd3=document.createElement("div"); var oTd4=document.createElement("div"); var oTd5=document.createElement("div"); var fldA=document.createElement("INPUT"); var fldB=document.createElement("INPUT"); var fldC=document.createElement("INPUT"); var fldD=document.createElement("INPUT"); var oButt=document.createElement("INPUT"); oTr.classList.add('row'); oTd1.classList.add('col'); oTd2.classList.add('col'); oTd3.classList.add('col'); oTd4.classList.add('col'); oTd5.classList.add('col'); fldA.setAttribute("type","text"); fldA.setAttribute("name","fldA"+num); fldB.setAttribute("type","text"); fldB.setAttribute("name","fldB"+num); fldC.setAttribute("type","text"); fldC.setAttribute("name","fldC"+num); fldD.setAttribute("type","text"); fldD.setAttribute("name","fldD"+num); oButt.setAttribute("type","button"); oButt.setAttribute("value","remove"); if(oButt.attachEvent) oButt.attachEvent('onclick',function(e){rimuovi(e);}) else if(oButt.addEventListener) oButt.addEventListener('click',function(e){removerow(e);},false) oTd1.appendChild(fldA); oTd2.appendChild(fldB); oTd3.appendChild(fldC); oTd4.appendChild(fldD); oTd5.appendChild(oButt); oTr.appendChild(oTd1); oTr.appendChild(oTd2); oTr.appendChild(oTd3); oTr.appendChild(oTd4); oTr.appendChild(oTd5); document.getElementById('form1').lastElementChild.after(oTr); num++ } } function removerow(e){ if(document.removeChild && document.getElementById && document.getElementsByTagName) { if(!e) e=window.event; var srg=(e.target)?e.target:e.srcElement; while(srg.tagName!="div" && !(srg.classList?.contains('row'))){srg=(srg.parentNode)?srg.parentNode:srg.parentElement} var tb=document.getElementById('form1').lastElementChild; <--- ERROR tb.removeChild(srg); } }
错误分析与修复
核心错误点
- 父元素定位错误:你把
tb设为表单的最后一个子元素,但要移除的行(srg)的直接父元素是整个表单(form1),并非最后一个子元素。调用tb.removeChild(srg)时,srg不是tb的子节点,因此报错。 - 行查找逻辑冗余:原循环查找
row的写法复杂且有漏洞,容易出现找不到目标行的情况。 - 过时API使用:
attachEvent是IE旧版专属API,现在主流浏览器均支持addEventListener,无需兼容。
修复后的JS代码
let num = 1; const form = document.getElementById('form1'); function addnewrow() { // 创建行容器 const row = document.createElement('div'); row.classList.add('row'); // 循环生成4个输入框列 const fieldPrefixes = ['A', 'B', 'C', 'D']; fieldPrefixes.forEach(prefix => { const col = document.createElement('div'); col.classList.add('col'); const input = document.createElement('input'); input.type = 'text'; input.name = `fld${prefix}${num}`; col.appendChild(input); row.appendChild(col); }); // 创建移除按钮列 const btnCol = document.createElement('div'); btnCol.classList.add('col'); const removeBtn = document.createElement('input'); removeBtn.type = 'button'; removeBtn.value = 'remove'; removeBtn.addEventListener('click', removerow); btnCol.appendChild(removeBtn); row.appendChild(btnCol); // 插入到表单最后一行之后 form.lastElementChild.after(row); num++; } function removerow(e) { // 直接找到点击按钮所在的最近row行 const currentRow = e.target.closest('.row'); if (currentRow && form.contains(currentRow)) { currentRow.remove(); } }
修复说明
- 使用
closest('.row')直接定位目标行,替代原有的循环查找,代码简洁且可靠。 - 调用
currentRow.remove()直接移除元素,无需手动查找父元素,符合现代DOM API的写法。 - 用循环生成输入框列,减少重复代码,提升可维护性。
- 提前获取表单元素,避免重复调用
getElementById。 - 移除过时的
attachEvent兼容代码,适配主流浏览器。
内容的提问来源于stack exchange,提问作者cucca
相关产品推荐
相关产品推荐

