jquery ui autocomplete:如何在文本输入失去焦点后取消缓慢的ajax请求
我正在使用 JQuery UI 自动完成字段,该字段与 ajax 查找相关,有时可能会相当慢。有时,用户会在 ajax 查询启动之后、ajax 调用返回之前离开文本输入字段。发生这种情况时,即使文本输入不再具有焦点,也会出现自动完成弹出窗口,并且关闭弹出窗口的唯一方法是选择一个项目(而不是按 Tab 键切换到另一个字段)。
事实上,这个 jquery ui demo 表现出相同的行为(例如输入 'ariz'进入文本字段,等待“搜索”动画出现,然后在返回任何结果之前按 Tab 键退出该字段)。
一种有效的解决方案(但感觉像是黑客)是检查ajax的成功回调以查看文本字段是否仍然具有焦点,如果不使用空列表调用response(),例如:
$( "#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 请求。
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).
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
}
}));
}
});
}
});
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
$.ajax
返回一个jqXHR
对象,并且对象公开底层XMLHttpRequest< 的
abort
方法 /代码> 对象。因此,您只需隐藏jqXHR
并在正确的时间中止请求。也许是这样的:然后你想要一些关于
#city
的东西:在自动完成器的正常操作期间有时会出现短暂的模糊/焦点,但只有当有人从列表中选择某些内容时才会发生这种情况;当发生这种情况时,不应该运行
$.ajax
请求,因此我们不需要担心它。如果我错了,那么您可以通过在blur
处理程序中使用计时器并在focus
回调中取消计时器来解决它(您可以将计时器 ID 存储在另一个.data()
插槽也是如此)。我还没有测试过这个,但我很确定它会起作用。
$.ajax
returns ajqXHR
object and that object exposes theabort
method of the underlyingXMLHttpRequest
object. So, you just need to stash thejqXHR
and abort the request at the right time. Something like this perhaps:And then you'd want some stuff on
#city
: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 theblur
handler and cancelling the timer in afocus
callback (you could store the timer-ID in another.data()
slot too).I haven't tested this but I'm pretty sure it will work.