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

动态添加表格行后change事件重复触发的解决方案求助

解决jQuery动态添加元素重复触发change事件的问题

问题场景

动态添加表格行时,为.gettotal类的输入框绑定change事件,但修改任意输入框的值时,会多次触发该事件,期望仅触发当前输入框对应的事件。

问题根源

每次点击.addnewjewel按钮添加新行时,都执行了$(".gettotal").change(...)——这会给所有已存在的.gettotal元素(包括之前添加的行里的输入框)重复绑定一次change事件。比如添加第2行时,第1行的输入框会被第二次绑定事件,修改时就会触发2次;添加第3行时,前两行的输入框各多一次绑定,以此类推,导致事件触发次数随添加行数递增。

解决方案

方案1:事件委托(推荐)

利用jQuery的事件委托机制,将事件绑定到静态存在的父元素(比如表格的tbody.addnewjewelbody),只绑定一次即可覆盖所有现有和未来添加的.gettotal元素,从根本上避免重复绑定。

修改后的完整代码:

$(document).ready(function(){
    // 事件委托:绑定到父元素,监听子元素的change事件
    $(".addnewjewelbody").on("change", ".gettotal", function(){
        console.log("changed");
        var grosstotal = 0;
        var weight = $(this).val();
        console.log(weight);
    });

    $(".addnewjewel").click(function(){
        $(".addnewjewelbody").append(`
            <tr id="${newjewelid}">
                <td><input type="text" name="jewelname" id="jewelname"></td>
                <td>
                    <input type="radio" id="Gold${newjewelid}" name="jeweltype+${newjewelid}">
                    <label for="Gold${newjewelid}">Gold</label>
                    <input type="radio" name="jeweltype+${newjewelid}" id="Silver${newjewelid}">
                    <label for="Silver${newjewelid}">Silver</label>
                </td>
                <td><input type="number" class="gettotal" name="newjewelweight" value="0" min="0" id="newjewelweight+${newjewelid}" step="0.01"></td>
                <td><input type="number" class="gettotal" name="currentrate" value="0" min="0" id="currentrate+${newjewelid}"></td>
                <td><input type="number" class="gettotal" name="makinhcharge" value="0" min="0" id="makinhcharge+${newjewelid}"></td>
                <td><input type="number" class="gettotal" name="othercharge" value="0" min="0" id="othercharge+${newjewelid}"></td>
                <td><input type="number" class="gettotal" name="GrossCharge" value="0" min="0" id="grosscharge+${newjewelid}"></td>
                <td></td>
            </tr>
        `);
        newjeweladded.push(newjewelid);
        newjewelid++;
        console.log(newjewelid);
        console.log(newjeweladded);
    });
});

方案2:仅给新添加的元素绑定事件

如果不想用事件委托,可以在添加新行后,只针对当前新行内的.gettotal元素绑定事件,而非全局选择所有.gettotal。

修改点击事件内的绑定代码:

$(".addnewjewel").click(function(){
    // 先append新行
    $(".addnewjewelbody").append(`
        <tr id="${newjewelid}">
            <td><input type="text" name="jewelname" id="jewelname"></td>
            <td>
                <input type="radio" id="Gold${newjewelid}" name="jeweltype+${newjewelid}">
                <label for="Gold${newjewelid}">Gold</label>
                <input type="radio" name="jeweltype+${newjewelid}" id="Silver${newjewelid}">
                <label for="Silver${newjewelid}">Silver</label>
            </td>
            <td><input type="number" class="gettotal" name="newjewelweight" value="0" min="0" id="newjewelweight+${newjewelid}" step="0.01"></td>
            <td><input type="number" class="gettotal" name="currentrate" value="0" min="0" id="currentrate+${newjewelid}"></td>
            <td><input type="number" class="gettotal" name="makinhcharge" value="0" min="0" id="makinhcharge+${newjewelid}"></td>
            <td><input type="number" class="gettotal" name="othercharge" value="0" min="0" id="othercharge+${newjewelid}"></td>
            <td><input type="number" class="gettotal" name="GrossCharge" value="0" min="0" id="grosscharge+${newjewelid}"></td>
            <td></td>
        </tr>
    `);
    newjeweladded.push(newjewelid);
    // 仅给当前新行的.gettotal绑定事件
    $(`#${newjewelid} .gettotal`).change(function(){
        console.log("changed");
        var grosstotal = 0;
        var weight = $(this).val();
        console.log(weight);
    });
    newjewelid++;
    console.log(newjewelid);
    console.log(newjeweladded);
});

说明

  • 事件委托是更优方案,只需绑定一次事件,性能更好,代码更简洁,适合频繁动态添加元素的场景。
  • 方案2虽然也能解决问题,但每次添加元素都要执行一次绑定逻辑,相比委托机制稍显冗余。

内容的提问来源于stack exchange,提问作者Abhi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 03:38:12