
本文解析 jQuery 中 success 回调意外执行两次的根本原因——事件监听器重复绑定,并提供结构清晰、可复用的修复方案,避免误删多行等严重副作用。
本文解析 jquery 中 success 回调意外执行两次的根本原因——事件监听器重复绑定,并提供结构清晰、可复用的修复方案,避免误删多行等严重副作用。
在使用 jQuery 3.5.1(及更高版本)进行 AJAX 操作时,若发现 success 回调被触发两次甚至多次,绝大多数情况下并非 AJAX 请求本身重复发送,而是事件处理函数被重复绑定所致。你提供的原始代码正是典型反例:
$(document).on('click', '.delc', function(e) {
// … 省略部分逻辑
$('#del-btn-customer').on('click', function(e){ // ⚠️ 危险:每次点击 .delc 都新增一个监听器!
$.ajax({ /* ... */ });
});
});问题核心在于:.delc 是动态生成或复用的删除按钮(委托到 document),每次用户点击它,都会为 #del-btn-customer 新增一次 .on('click', ...) 监听器。若用户快速点击两次 .delc(例如弹窗未关闭前又点了一次),则 #del-btn-customer 上将累积两个完全相同的 AJAX 调用监听器——一旦最终点击确认按钮,两个请求并发发出,成功后各自执行 fadeOut().remove(),导致视觉上“删了两行”。
✅ 正确做法是解耦事件绑定逻辑:
jQuery 1.12.4是jQuery 1.x系列的最后一个正式稳定版本,由jQuery团队于2016年发布。该版本主要面向需要兼容旧版浏览器环境的网站和Web应用,尤其适用于仍需支持Internet Explorer 6、Internet Explorer 7、Internet Explorer 8等老旧浏览器的项目。
- 将模态框触发逻辑(获取
id、item、显示弹窗)保留在.delc点击中; -
但将
#del-btn-customer的点击监听器单独声明、且仅绑定一次(通常在$(document).ready()内顶层作用域完成)。
修复后的推荐写法如下:
$(document).ready(function() {
let currentItemId = null;
let currentItemElement = null;
// 1. 绑定删除触发按钮(委托)
$(document).on('click', '.delc', function(e) {
e.preventDefault();
console.log("Delete trigger clicked");
currentItemId = $(this).closest('.delc').attr('rel');
currentItemElement = $(this).closest('tr'); // 更健壮:用 closest('tr') 替代 parent().parent()
$('#mdl-avviso-customer').modal('show');
});
// 2. ✅ 单独、一次性绑定确认按钮(非委托,假设 #del-btn-customer 是静态 DOM)
$('#del-btn-customer').on('click', function(e) {
e.preventDefault();
if (!currentItemId || !currentItemElement) return; // 安全防护
$.ajax({
url: 'php/del_customer.php',
type: 'POST',
data: { id: currentItemId }, // 推荐使用对象格式,更安全清晰
cache: false,
dataType: 'json', // 显式指定响应类型,便于调试
success: function(response) {
currentItemElement.fadeOut(300, function() {
$(this).remove();
});
// 可选:重置状态 & 关闭模态框
$('#mdl-avviso-customer').modal('hide');
currentItemId = null;
currentItemElement = null;
},
error: function(xhr, status, err) {
console.error('Delete failed:', status, err);
alert('删除失败,请重试。');
}
});
});
});? 关键注意事项:
-
永远避免在事件回调内重复调用
.on()绑定同一目标元素的同一事件; - 使用
let声明块级作用域变量(如currentItemId)替代全局var,防止跨操作污染; - 推荐用
$(this).closest('tr')替代链式parent().parent(),语义更清晰、容错性更强; - AJAX 请求中使用对象形式传参(
{id: ...})比拼接字符串更安全,自动处理编码; - 添加
error回调和空值校验,提升健壮性; - 若
#del-btn-customer也是动态生成的,需改用委托方式绑定:$(document).on('click', '#del-btn-customer', function(e) { ... });
遵循以上模式,即可彻底杜绝 success 回调重复执行问题,确保每一步操作精准可控。

















