You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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">
            &nbsp;
        </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);
    }
}

错误分析与修复

核心错误点

  1. 父元素定位错误:你把tb设为表单的最后一个子元素,但要移除的行(srg)的直接父元素是整个表单(form1),并非最后一个子元素。调用tb.removeChild(srg)时,srg不是tb的子节点,因此报错。
  2. 行查找逻辑冗余:原循环查找row的写法复杂且有漏洞,容易出现找不到目标行的情况。
  3. 过时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 11:18:08