这是我的代码:
$(document).on('click', '[data-submit-form]', function (event) {
var form = $(this).closest('form');
$.ajax({
url : form.attr('action'),
type : 'post',
data: form.serialize(),
async: false,
success: function (data) {
if ($.type(data) === 'object') {
alert_errors(form, data);
event.stopImmediatePropagation()
}
}
});
});
单击按钮时,使用AJAX检查服务器是否有错误。如果有错误,则返回包含错误的对象。如果出现错误,我想停止在单击的按钮上发生所有其他事件。例如,该按钮也可用于关闭模态。如果有错误,我想阻止这种情况发生。
这根本不起作用。在显示警报后,似乎event.stopImmediatePropagation()对按钮的其他事件没有影响。
答案 0 :(得分:2)
这里的问题与同步或异步代码无关。
是的,如果您的AJAX调用是异步的,那么这将是一个问题,因为事件委托是同步的,不会等待您的AJAX调用返回。但是您的呼叫是同步的,因为您设置了async: true
。
这里真正的潜在问题是时间。
您正在进行的HTTP请求 - 即使它是同步的,因为您设置了async: false
- 需要一些时间来完成,并且当它完成时,浏览器的事件委派已经发生,因此您的event.stopImmediatePropagation()
无效。
理想情况下,您需要将event.stopImmediatePropagation
移至另一个位置,如下所示:
$(document).on('click', '[data-submit-form]', function (event) {
var form = $(this).closest('form');
event.stopImmediatePropagation(); // Do it here
$.ajax({
url : form.attr('action'),
type : 'post',
data: form.serialize(),
async: false,
success: function (data) {
if ($.type(data) === 'object') {
alert_errors(form, data);
// event.stopImmediatePropagation() NOT here
}
}
});
});
修改强>
您当前的方法并不是您尝试做的最理想的方法,因为您的模态关闭和表单提交逻辑太紧密耦合,因为它们处于相同的单击事件中。
您应该使用单独的函数使进程略微更精细,而不是使提交表单单击事件也关闭模式:
使用这种方法,您的代码可以保持原样,并在成功回调中调用closeModal函数,如下所示:
// By default, this will NOT close the modal anymore. You must explicitly
// call 'closeModal' where you want, e.g. in the AJAX success callback.
// This type of granularity will be much more flexible and save you headache.
$(document).on('click', '[data-submit-form]', function (event) {
var form = $(this).closest('form');
$.ajax({
url : form.attr('action'),
type : 'post',
data: form.serialize(),
async: false,
success: function (data) {
if ($.type(data) === 'object') {
alert_errors(form, data);
closeModal(); // Close modal
}
}
});
});
这样的方法更加清晰,因为随着您的功能的增长和增长,您将不断发现自己需要调用preventDeafult
,stopPropagation
的越来越多的奇怪场景, stopImmediatePropagation
,等等,我保证你会再次遇到同样的问题。这只会是一团糟。
现在为自己省去麻烦。
答案 1 :(得分:0)
在处理完成后,您无法阻止事件处理。事件的顺序如下:
用户点击按钮
基于此response,您的代码应该是:
$(document).on('click', '[data-submit-form]', function (event) {
var form = $(this).closest('form');
var data= JSON.parse(
$.ajax({
url : form.attr('action'),
type : 'post',
data: form.serialize(),
async: false
}).responseText; //The ajax call returns the response itself
if ($.type(data) === 'object') {
alert_errors(form, data);
//event.stopImmediatePropagation()
} else {
//rest of the event handling
}
});
但是无论如何我认为你应该使用异步调用,因为浏览器甚至jQuery都不推荐使用同步调用(文档已经删除了所有同步示例并阻止了它的使用)