使用bootbox.dialog异步提交表单时,多次回车重复触发回调函数的问题
解决Bootbox对话框回车多次触发回调的问题
快速按下回车键多次时,对话框的回调函数会被多次触发,按下次数越多,触发次数也越多。尝试在点击按钮后禁用它直到API返回结果,但设置按钮禁用无效,希望实现即使多次按回车,回调也只执行一次。
测试浏览器:Chrome 50.0.2661.94 m、Firefox 43.0.1
原始代码
HTML代码
<div id="test"> </div>
JS代码
var count = 0; bootbox.dialog({ title: 'test', message: '<form action="https://catfact.ninja/fact">test</form>', buttons: { success: { label: 'ok', className: 'btn-success', callback: function () { var close = false; var submitForm = $(this).find('form'); submitForm.ajaxSubmit({ block: true, dataType: 'json', async: false, success: function (result) { console.log('res', result) $('#test').append('<br>' + (++count)); if (result.fact) { close = true; } else { close = false; } }, error: function (err) { close = false; } }) return close; } } } })
解决方案
核心思路是标记请求状态避免重复触发,同时正确禁用按钮直到请求完成,另外建议将同步AJAX改为异步以提升浏览器体验:
修改后的JS代码
var count = 0; var isProcessing = false; // 标记是否正在处理请求 bootbox.dialog({ title: 'test', message: '<form action="https://catfact.ninja/fact">test</form>', buttons: { success: { label: 'ok', className: 'btn-success', callback: function () { // 正在处理时直接返回,阻止重复触发 if (isProcessing) { return false; } isProcessing = true; var $btn = $(this).find('.btn-success'); $btn.prop('disabled', true); // 禁用按钮 var close = false; var submitForm = $(this).find('form'); // 改为异步AJAX,避免阻塞浏览器 submitForm.ajaxSubmit({ block: true, dataType: 'json', async: true, success: function (result) { console.log('res', result) $('#test').append('<br>' + (++count)); close = !!result.fact; // 若需自动关闭对话框,可在此调用 bootbox.hideAll() }, error: function (err) { close = false; }, complete: function() { // 请求完成后恢复状态 isProcessing = false; $btn.prop('disabled', false); // 重新启用按钮 } }); // 异步请求下先返回false,阻止对话框提前关闭 return close; } } } })
关键改动说明
- 新增
isProcessing变量标记请求状态,回调触发时先判断,彻底避免重复执行 - 找到按钮元素并在请求开始时禁用,请求完成后统一恢复可用状态
- 将
async: false改为async: true,消除浏览器阻塞问题 - 利用AJAX的
complete回调统一处理状态恢复,无论请求成功或失败都会执行
内容的提问来源于stack exchange,提问作者jeffierw
相关产品推荐
相关产品推荐

