Javascript jQuery:仅当页面上当前没有运行AJAX时才提交表单
当城市输入字段模糊时,我通过ajax请求获得somnething,并将其设置为隐藏字段的值,格式与城市字段相同Javascript jQuery:仅当页面上当前没有运行AJAX时才提交表单,javascript,jquery,ajax,Javascript,Jquery,Ajax,当城市输入字段模糊时,我通过ajax请求获得somnething,并将其设置为隐藏字段的值,格式与城市字段相同 $('input#city').on('blur', function() { $.ajax({ url: 'get/something?param=val', success: function(response) { $('input:hidden[name="something"]').val(response);
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
}
});
});
如果用户在模糊城市字段后立即提交表单,有时由于延迟,隐藏字段不会填充,因为另一端的SQL花费的时间太长
这两个字段的格式也通过ajax提交:
$('form#find-users').on('submit', function() {
if(NO_AJAX_CURRENTLY_RUNNING_ON_PAGE) {
// do stuff
}
});
如何检测页面上是否没有运行ajax?这将确保在处理表单之前完成城市ajax并填充隐藏字段
编辑
实际上不会,它只会阻止表单提交。但如果我能检测到,那么我可以使用setInterval并继续尝试运行该代码,直到它运行为止,因为ajax已经完成。理想情况下,jQuery中会有一些东西等待其他ajax完成后再提交。您可以在全局名称空间中放置一个变量,可能名为
ajaxLock
,并在ajax启动时将其打开,在响应到来时将其关闭。然后在允许提交之前检查它
差不多
var ajaxLock = 1;
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
ajaxLock = 0;
}
});
});
按照建议使用锁定变量:
$('input#city').on('blur', function() {
window.AJAX_CURRENTLY_RUNNING_ON_PAGE = true;
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
},
complete: function() { window.AJAX_CURRENTLY_RUNNING_ON_PAGE = false; }
});
});
$('form#find-users').on('submit', function() {
if(window.AJAX_CURRENTLY_RUNNING_ON_PAGE) {
return;
}
//dostuff
});
在这种情况下,我可以使用block ui之类的插件或禁用表单提交按钮,原因是您需要在设计中具有交互性,您可以很好地锁定表单提交,但最好给出一条消息或使用模式灰显使用jQuery。只要所有Ajax调用都是使用jQuery生成的,就可以知道是否有任何Ajax调用未完成
$(document).ready(function() {
var ajaxBusy = false;
$(document).ajaxStart( function() {
ajaxBusy = true;
}).ajaxStop( function() {
ajaxBusy = false;
});
});
编辑:
这就回答了您直接提出的问题:“我如何知道是否有Ajax调用正在运行。”
或者,您可以在运行模糊处理程序时禁用表单的提交按钮,然后在完成后重新启用它
$('input#city').on('blur', function() {
var submit = $(this).closest('form').find(':submit:enabled');
submit.prop('disabled', true);
$.ajax('get/something?param=val').done(function(response) {
$('input:hidden[name="something"]').val(response);
}).always(function() {
submit.prop('disabled', false);
});
});
编辑2:
因此,现在我们要推迟表单提交,直到所有当前Ajax调用完成。我们允许人们点击submit按钮,但是如果有未决的Ajax调用,我们不会马上做任何事情
我们可以用一个对象来帮助我们
$(document).ready(function() {
var ajaxDefer = $.Deferred().resolve();
$(document).ajaxStart( function() {
ajaxDefer = $.Deferred();
}).ajaxStop( function() {
ajaxDefer.resolve();
});
$('form#find-users').on('submit', function() {
ajaxDefer.always(function() {
// Code here will always be executed as soon as there are no
// Ajax calls running.
// this points to the deferred object (ajaxDefer), so use the closure
// to carry over any variables you need.
});
});
});
ajaxDefer
对象设置为解析状态。这意味着使用.always()
附加的任何函数都将立即执行ajaxDefer
对象。使用ajaxDefer.always()
附加的任何新函数都将推迟到以后ajaxDefer.resolve()
,这将导致执行所有未执行的延迟函数。现在我们回到初始状态,任何新附加的函数都将立即执行ajaxDefer
。它将在适当的时候执行,这取决于是否有任何未完成的Ajax请求。注意你的闭包使用此选项检查当前是否正在使用JQuery进行AJAX调用:
if ($.active == 0) {
...
}
如果失败了怎么办?您应该使用complete而不是success来切换标志。我不知道他会允许失败就屈服。它可能应该关闭“打开-完成…”。。。对我来说,我会把它放在一个普通回调上。直到ajaxStart/ajaxStop。谢谢你的建议!第二种选择在两个方面更好。(1) 你不应该允许人们点击那些还没有做任何事情的按钮,(2)你不需要设置任何定时器或重试时间间隔来在所有其他ajax功能完成后提交表单。如果你真的坚持走第一条路,那么如果你用一个延迟的对象来完成任务,你的生活就会变得更轻松。如果您愿意,我可以提供一个代码示例。@slashingweapon yea通常我只会禁用submit按钮,但在这种情况下,第一个选项是正确的。ajax调用从数据库中获取城市的纬度和经度,并将其设置为2个隐藏字段的值。因为如果我禁用submit按钮,字段是隐藏的,用户不知道为什么会这样做。他会看到表单的其余部分被正确填写,不理解并认为该站点已被破坏。@slashingweapon但我希望您能举一个例子,说明您对ajax busy使用延迟对象的意思,因为现在我正在使用setInterval并在成功处理表单时将其清除。@slashingweapon非常感谢您的更新,将改为使用延迟。