jquery ui autocomplete:如何在文本输入失去焦点后取消缓慢的ajax请求

我正在使用一个与ajax查找绑定的JQuery UI自动完成字段,有时可能会相当慢。 在ajax查询启动之后但 ajax调用返回之前 ,用户偶尔会远离文本输入字段。 发生这种情况时,即使文本输入不再具有焦点,也会显示自动完成弹出窗口,并且解除弹出窗口的唯一方法是选择一个项目(而不是标记到另一个字段)。

实际上,这个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请求。

$.ajax返回一个jqXHR对象,该对象公开底层XMLHttpRequest对象的abort方法 。 因此,您只需要存储jqXHR并在合适的时间中止请求。 也许这样的事情:

 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'); }); 

在自动完成程序的正常操作期间,有时会出现短暂的模糊/焦点,但这只会在有人从列表中选择某些内容时发生; 当发生这种情况时,不应该运行$.ajax请求,因此我们不需要担心它。 如果我错了,那么你可以通过在blur处理程序中使用一个计时器并在focus回调中取消计时器来克服它(你也可以将计时器ID存储在另一个.data()槽中)。

我没有测试过这个,但我很确定它会起作用。