jQuery Ajax重复触发问题:DataTable场景下接口多次调用原因咨询
DataTables+jQuery Ajax重复触发请求的原因及修复
问题场景
点击表格行多次后,再点击模态框内的btn1按钮,ajax/InsertNames.php会被重复调用,调用次数等于之前点击表格行的次数,且每次请求数据相同。用one()绑定事件能临时解决,但想明确重复触发的根本原因。
原代码
$("#field1").change(function () { var table = $('#config-table').DataTable({ responsive: true, processing : true, scrollY: false, scrollX: false, destroy: true, // 其他配置... }); $('#config-table tbody').on('click', 'tr', function () { var data = table.row(this).data(); console.log(table.row(this).data()); $('#name1').val(data["name1"]); $("#responsive-modal").modal("show"); // Button inside the modal $('#btn1').click(function(){ var name1 = $("#name1").val(); var name2 = $("#name2").val(); $.ajax({ url: "ajax/InsertNames.php", type: "POST", data: { name1 : name1, name2 : name2 // and more }, dataType: "json", cache: false, success: function () { $('#config-table').DataTable().ajax.reload(null, false); $("#responsive-modal").modal("hide"); }, error: function () { alert("ERROR"); } }); }); }); });
重复触发的根本原因
每次点击表格行时,都会执行$('#btn1').click(...)代码,给同一个按钮新增一次点击事件绑定,但之前绑定的事件并不会自动移除。比如:
- 第一次点击表格行:
btn1绑定1次点击事件 - 第二次点击表格行:
btn1再绑定1次,此时共有2个点击事件 - 第三次点击表格行:
btn1绑定第3次事件
当你点击btn1时,所有已绑定的点击事件都会依次执行,导致Ajax请求被重复触发。
用one()能解决是因为one()绑定的事件只会执行一次,执行后会自动解绑,但每次点击表格行仍会给btn1绑定新的one()事件,本质还是重复绑定,只是每次点击按钮只触发一次,并非最优解决方案。
正确的修复方式
方案1:将按钮事件移到表格行点击事件外部
模态框和按钮是页面固定元素,不需要每次点击表格行都重新绑定事件,只需在页面初始化时绑定一次即可:
$("#field1").change(function () { var table = $('#config-table').DataTable({ responsive: true, processing : true, scrollY: false, scrollX: false, destroy: true, // 其他配置... }); // 页面初始化时绑定一次btn1的点击事件 $('#btn1').click(function(){ var name1 = $("#name1").val(); var name2 = $("#name2").val(); $.ajax({ url: "ajax/InsertNames.php", type: "POST", data: { name1 : name1, name2 : name2 // and more }, dataType: "json", cache: false, success: function () { $('#config-table').DataTable().ajax.reload(null, false); $("#responsive-modal").modal("hide"); }, error: function () { alert("ERROR"); } }); }); // 表格行点击仅负责填充数据和显示模态框 $('#config-table tbody').on('click', 'tr', function () { var data = table.row(this).data(); console.log(data); $('#name1').val(data["name1"]); $("#responsive-modal").modal("show"); }); });
方案2:绑定前先解绑旧事件(适合必须在内部绑定的场景)
如果因为业务逻辑限制,必须在表格行点击事件内绑定按钮事件,那么每次绑定前先解绑按钮上已有的点击事件:
$("#field1").change(function () { var table = $('#config-table').DataTable({ responsive: true, processing : true, scrollY: false, scrollX: false, destroy: true, // 其他配置... }); $('#config-table tbody').on('click', 'tr', function () { var data = table.row(this).data(); console.log(data); $('#name1').val(data["name1"]); $("#responsive-modal").modal("show"); // 先解绑所有旧的点击事件,再绑定新事件 $('#btn1').off('click').click(function(){ var name1 = $("#name1").val(); var name2 = $("#name2").val(); $.ajax({ url: "ajax/InsertNames.php", type: "POST", data: { name1 : name1, name2 : name2 // and more }, dataType: "json", cache: false, success: function () { $('#config-table').DataTable().ajax.reload(null, false); $("#responsive-modal").modal("hide"); }, error: function () { alert("ERROR"); } }); }); }); });
内容的提问来源于stack exchange,提问作者walter
相关产品推荐
相关产品推荐

