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

动态加载内容引发Ajax请求重复触发问题求助

动态生成内容的jQuery事件绑定与JS重复执行问题

我使用Bootstrap 4开发项目,通过Ajax请求根据ID加载模态框,模态框内的「添加」按钮可正常为对应ID的表格添加行。现在希望为表格添加「删除」按钮,点击时触发Ajax请求删除该行且无需刷新页面,但由于DOM已加载,动态生成的内容无法绑定jQuery事件,导致点击无响应。

尝试将JS文件加入动态加载内容后,「添加」功能会触发两次,删除2行后甚至触发6次,次数递增。求正确的加载方案,让JS函数仅执行一次且正常生效。


加载模态框的JS代码

jQuery(function($) {
    $('.view_datainDelen').click(function() {
        var uitgaveid = $(this).attr("id");
        getBetaalInDeleninfo(uitgaveid);
    });
});
        
function getBetaalInDeleninfo(uitgaveid) {
    $.ajax({
        url: 'dynamicData/GetBetalingInfo.php?type=betaalindeleninfo',
        method:"post",
        data:{rowid:uitgaveid},
        success:function(data){
            $('#BetaalInDelenInfo').html(data);
            $('#BetaalInDelenModal').modal("show");
            getBetalingInDelenTabel(uitgaveid);
        }
    });
}

生成表格内容的PHP代码

if(isset($_GET['uitgaveid']) && is_numeric($_GET['uitgaveid'])) {
    $uitgaveid = tekst($_GET['uitgaveid']);
    
    //Table met deelbetalingen
    $qDeelbetalingen = $mysqli->query(" ##Query not important for the purpose of this question                      
                                    ");
                                    
    $totaalbedrag = 0;
    $output = '';
    while($db = $qDeelbetalingen->fetch_assoc()) {
        
        $output .= '
                    <tr>
                        <td>'.$db['betaaldOp'].'</td>
                        <td class="text-right text-nowrap">'.euro($db['bedrag']).'</td>
                        <td class="text-right text-nowrap">
                            <button class="btn btn-link btn-sm submit_verwijderdeelbetaling" id="'.$db['uitgavedeelbetalingid'].'">
                                <span class="fas fa-trash fa-fw"></span>
                            </button>
                        </td>
                    </tr>
                    ';
        
        $totaalbedrag = $totaalbedrag + $db['bedrag'];
    }
    $output .= '
                <tr>
                    <td><strong>Totaal:</strong></td>
                    <td class="text-right text-nowrap"><strong>'.euro($totaalbedrag).'</strong></td>
                    
                    <td>&nbsp;</td>
                </tr>
                ';
    
    echo $output;
    
} else {
    echo 'Ongeldige ID';
}

尝试过的JS代码

jQuery(function($) {
    $('.view_datainDelen').click(function() {
        var uitgaveid = $(this).attr("id");
        getBetaalInDeleninfo(uitgaveid);
    });
    
    $('.submit_verwijderdeelbetaling').click(function(e){
        e.preventDefault(); 
        
        var uitgavedeelbetalingid   = $(this).attr('id');
        var uitgaveid               = $("#uitgaveid").val();
        VerwijderBetaalInDelen(uitgaveid, uitgavedeelbetalingid);
    });
    
    $('#submit_deelbetaling').click(function(e){
        e.preventDefault(); 
        
        var uitgaveid   = $("#uitgaveid").val();
        var betaaldOp   = $("#betaaldOp").val();
        var bedrag      = $("#bedrag").val();
        
        NieuwBetaalInDelen(uitgaveid, betaaldOp, bedrag);
            
    });
});

function VerwijderBetaalInDelen(uitgaveid, uitgavedeelbetalingid) {
    $.ajax({
        type:   'post',
        url:    'DataHandlers/administratiedeelbetaling.handler.php?type=verwijder',
        data: { formulier: 'VerwijderDeelbetaling',
                uitgaveid: uitgaveid,
                uitgavedeelbetalingid: uitgavedeelbetalingid
            },
        success: function(html){
                getBetalingInDelenTabel(uitgaveid);
                
                $("script[src='/js/deelbetalingen.js']").remove()
            },
        complete: function() {
                $.getScript("/js/deelbetalingen.js", function() {});
            }
    });
}

function NieuwBetaalInDelen(uitgaveid, betaaldOp, bedrag) {
    $.ajax({
        type:   'post',
        url:    'DataHandlers/administratiedeelbetaling.handler.php?type=nieuw',
        data: { formulier: 'deelbetaling',
                uitgaveid: uitgaveid,
                betaaldOp: betaaldOp,
                bedrag: bedrag
            },
        success: function(html){
                getBetalingInDelenTabel(uitgaveid);
                
                $("script[src='/js/deelbetalingen.js']").remove()
            },
        complete: function() {
                $.getScript("/js/deelbetalingen.js", function() {});
            }
    });
}

解决方案:事件委托+避免重复绑定

1. 用事件委托解决动态元素绑定问题

不要直接给动态生成的.submit_verwijderdeelbetaling绑定事件,而是把事件绑定到页面加载时就存在的父元素(比如模态框容器#BetaalInDelenInfo),利用jQuery的事件委托机制:

修改JS中的点击事件绑定:

jQuery(function($) {
    $('.view_datainDelen').click(function() {
        var uitgaveid = $(this).attr("id");
        getBetaalInDeleninfo(uitgaveid);
    });
    
    // 事件委托到模态框容器
    $('#BetaalInDelenInfo').on('click', '.submit_verwijderdeelbetaling', function(e){
        e.preventDefault(); 
        
        var uitgavedeelbetalingid   = $(this).attr('id');
        var uitgaveid               = $("#uitgaveid").val();
        VerwijderBetaalInDelen(uitgaveid, uitgavedeelbetalingid);
    });
    
    $('#submit_deelbetaling').click(function(e){
        e.preventDefault(); 
        
        var uitgaveid   = $("#uitgaveid").val();
        var betaaldOp   = $("#betaaldOp").val();
        var bedrag      = $("#bedrag").val();
        
        NieuwBetaalInDelen(uitgaveid, betaaldOp, bedrag);
            
    });
});

2. 移除重复加载JS的逻辑

你之前在VerwijderBetaalInDelen和NieuwBetaalInDelen的Ajax回调里重复加载JS文件,会导致事件被多次绑定,直接删除以下代码:

$("script[src='/js/deelbetalingen.js']").remove()
// 以及
$.getScript("/js/deelbetalingen.js", function() {});

3. 确保JS只加载一次

把deelbetalingen.js作为静态资源在页面头部或底部引入一次即可,不需要动态加载:

<script src="/js/deelbetalingen.js"></script>

这样处理后,动态生成的删除按钮能正常触发事件,添加/删除功能也不会出现重复执行的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 21:55:03