jQuery用户界面自动完成:如何取消缓慢AJAX请求后,文本输入失去焦点 [英] jquery ui autocomplete: how to cancel slow ajax request after text input loses focus
问题描述
我使用的是依赖于一个Ajax查找,可以在时间相当缓慢的JQuery用户界面自动完成场。有时用户会的标签后远离文本输入字段的阿贾克斯查询同修但之前的AJAX调用返回。发生这种情况时,自动完成弹出的出现,即使在文字输入不再具有焦点,并关闭弹出的唯一方法是选择一个项目(而不是跳格到另一个字段)。
I'm using an JQuery UI Autocomplete field that is tied to an ajax lookup that can be rather slow at times. Occasionally a user will tab away from the text input field after the ajax query initiates but before the ajax call returns. When this happens, the autocomplete pop-up appears even though the text input no longer has focus, and the only way to dismiss the popup is by selecting an item (rather than tabbing to another field).
其实,这 jQuery UI的演示表现出相同的行为(例如输入亚利桑那州进文本字段,等待'搜索'的动画出现,然后切换出该领域之前,它返回任何结果)。
In fact, this jquery ui demo exhibits the same behavior (for example enter 'ariz' into the text field, wait for the 'searching' animation to appear and then tab out of the field before it returns any results).
一个解决方案,工程(但感觉就像一个黑客)是检查在阿贾克斯的成功回调,看看文本字段仍具有焦点,如果没有呼叫响应()与空列表,例如:
One solution that works (but feels like a hack) is to check in the ajax's success callback to see if the text field still has focus, and if not to call response() with an empty list, for example:
$( "#city" ).autocomplete({
var elem = this.element;
source: function( request, response ) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
data: {name_startsWith: request.term},
success: function( data ) {
if(!$(elem).is(':focus') {
response({});
return;
}
response( $.map( data.geonames, function( item ) {
return {
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name
}
}));
}
});
}
});
有没有更优雅的解决方案吗?理想情况下,我想尽快取消Ajax请求的用户标签远离文本输入字段。
Is there a more graceful solution? Ideally I'd like to cancel the ajax request as soon as the user tabs away from the text input field.
推荐答案
$。阿贾克斯
返回的 jqXHR
对象,该对象公开的 中止
的方法底层 XMLHtt prequest
对象。所以,你只需要藏匿的 jqXHR
并中止在正确的时间要求。事情是这样的可能:
$.ajax
returns a jqXHR
object and that object exposes the abort
method of the underlying XMLHttpRequest
object. So, you just need to stash the jqXHR
and abort the request at the right time. Something like this perhaps:
source: function(request, response) {
var $this = $(this);
var $element = $(this.element);
var jqXHR = $element.data('jqXHR');
if(jqXHR)
jqXHR.abort();
$element.data('jqXHR', $.ajax({
// ...
complete: function() {
// This callback is called when the request completes
// regardless of success or failure.
$this.removeData('jqXHR');
// And dismiss the search animation.
response({});
}
});
}
然后你想要一些东西 #city
:
$('#city').blur(function() {
var $this = $(this);
var jqXHR = $(this).data('jqXHR');
if(jqXHR)
jqXHR.abort();
$this.removeData('jqXHR');
});
有一个短暂的模糊/的autocompleter的正常运行过程中有时会关注,但是,当,当有人选择从列表中的东西,只有发生;不应该有一个 $。阿贾克斯
要求运行时,出现这种情况,所以我们并不需要担心。如果我错了,那么你可以通过一个定时器模糊
处理程序中,取消了重点计时器$ C $它周围的组装机C>回调(你可以存储的定时器ID在另一个
的.data()
插槽也是如此)。
There is a brief blur/focus sometimes during the autocompleter's normal operation but that only happens when when someone chooses something from the list; there shouldn't be a $.ajax
request running when that happens so we don't need to worry about it. If I'm wrong then you can kludge around it by using a timer inside the blur
handler and cancelling the timer in a focus
callback (you could store the timer-ID in another .data()
slot too).
我没有测试过这一点,但我是pretty的肯定它会工作。
I haven't tested this but I'm pretty sure it will work.
这篇关于jQuery用户界面自动完成:如何取消缓慢AJAX请求后,文本输入失去焦点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!