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

jQuery动态生成的select选中值无法触发事件如何解决

问题根因

动态生成的行下拉框不触发事件,是三个低级错误导致的:

  • 给.sell绑定change事件时用了直接绑定,这种方式只能匹配页面初始加载时就存在的元素,后续动态插入的.sell节点没有绑定事件,自然不会触发逻辑
  • 动态生成的元素重复使用了mySelect、comments_remove等id,HTML规范要求id在页面中全局唯一,重复id会导致元素获取永远命中第一个节点,逻辑完全混乱
  • 额外写的genfun函数存在上下文错误:内联onchange调用时函数内this指向window,根本拿不到当前触发事件的select节点,属于冗余无效代码
修复后完整代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="table-responsive">
    <table class="table table-review review-table mb-0" id="table_achievements">
        <thead>
            <tr>
                <th style="width:40px;">序号</th>
                <th>字段</th>
                <th>匹配规则</th>
                <th>匹配值</th>
                <th>逻辑符</th>
                <th style="width:92.56px;">操作</th>
            </tr>
        </thead>
        <tbody id="table_achievements_tbody">
            <tr>
                <td>1</td>
                <td>
                    <select class="form-control">
                        <option>Field Name</option>
                        <option>Div Awada</option>
                        <option>Div Vlad</option>
                    </select>
                </td>
                <td>
                    <select class="form-control">
                        <option>Equals</option>
                        <option>Greater than</option>
                        <option>Less than</option>
                    </select>
                </td>
                <td><input type="text" class="form-control" placeholder="Enter Value" ></td>
                <td style="width: 120px;">
                    <select class="form-control sell" name="argSelect" >
                        <option value="Arg">Argument</option>
                        <option value="AND">AND</option>
                        <option value="OR">OR</option>
                        <option value="ONLY">ONLY</option>
                    </select>
                </td>
                <td></td>
            </tr>
        </tbody>
    </table>
</div>

<script>
$(function () {
    // 事件委托绑定到永久存在的父级tbody,覆盖所有动态生成的.sell节点
    $('#table_achievements_tbody').on('change', '.sell', function () {
        const $currentSelect = $(this);
        const $table = $currentSelect.closest("table.table-review");
        const tableId = $table.attr('id');
        const selectVal = $currentSelect.val();
        
        if(selectVal === "AND" || selectVal === "OR"){
            const $newRow = $("<tr />");
            $newRow.html(buildNewRow(tableId));
            $("#"+tableId+"_tbody").append($newRow);
            // 当前行已经选过逻辑符,禁用对应选项避免重复触发生成多行
            $currentSelect.find('option[value="AND"], option[value="OR"]').prop('disabled', true);
        }
    });

    // 删除按钮同样用事件委托,用class选择器替代重复id
    $('#table_achievements_tbody').on("click", ".comments_remove", function () {
        const $currentRow = $(this).closest("tr");
        const $prevRow = $currentRow.prev();
        // 恢复上一行的逻辑符可选项、显示删除按钮
        $prevRow.find('.sell option').prop('disabled', false);
        $prevRow.find('td:last-child').html('<button type="button" class="btn btn-danger comments_remove"><i class="fa fa-trash-o"></i></button>');
        $currentRow.remove();
        // 重新计算行号
        refreshRowIndex();
    });

    // 构建新行内容,移除所有重复id和内联事件
    function buildNewRow(table_id) {
        const tbody = document.getElementById(table_id).getElementsByTagName("tbody")[0];
        const rowIndex = tbody.getElementsByTagName("tr").length + 1;
        return `
            <td>${rowIndex}</td>
            <td>
                <select name="DynamicTextBox" class="select form-control">
                    <option>Field Name</option>
                    <option>Div Awada</option>
                    <option>Div Vlad</option>
                </select>
            </td>
            <td>
                <select name="DynamicTextBox" class="select form-control">
                    <option>Field Name</option>
                    <option>Equals</option>
                    <option>Greater than</option>
                </select>
            </td>
            <td><input type="text" name="DynamicTextBox" class="form-control" placeholder="Enter Value"></td>
            <td>
                <select class="form-control sell" name="argSelect">
                    <option value="Arg">Argument</option>
                    <option value="AND">AND</option>
                    <option value="OR">OR</option>
                    <option value="ONLY">ONLY</option>
                </select>
            </td>
            <td><button type="button" class="btn btn-danger comments_remove"><i class="fa fa-trash-o"></i></button></td>
        `
    }

    // 刷新行号
    function refreshRowIndex(){
        $('#table_achievements_tbody tr').each(function(index){
            $(this).find('td:first').text(index+1);
        })
    }
});
</script>
修改点说明
  • 所有动态元素的事件统一用jQuery事件委托绑定到初始就存在的tbody节点上,不管后续新增多少行,事件都能正常触发
  • 移除所有重复id和内联onchange绑定,删除冗余的genfun函数,逻辑统一收敛
  • 新增逻辑符选项禁用逻辑,选完AND/OR生成新行后,当前行的AND/OR选项会被禁用,避免重复选导致无限新增行
  • 新增行号刷新逻辑,删除行后序号自动重排,不会出现序号错乱
  • 删除行时自动恢复上一行的逻辑符可选状态和删除按钮,交互更合理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 04:06:51