动态加载内容引发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> </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
相关产品推荐
相关产品推荐

