【问题标题】:How does JQueryUI Autocomplete handle asynchronous results?JQueryUI Autocomplete 如何处理异步结果?
【发布时间】:2014-04-18 17:03:29
【问题描述】:

我无法理解 JQueryUI 的自动完成功能如何处理导致异步结果的重复按键。我需要具有类似功能的东西,但我无法正确输入自动完成的结果。一个例子:

$(document).ready(function() {
    $('#textinput').live('keyup', function() {
        $.get('bacon.php', function(data) {
             $('#holder').html(data);
        });
    });
});

问题在于,如果快速输入,结果通常不会以正确的顺序返回。如果我输入单词“KEY”,我可能会返回“K”的结果,然后是“KEY”,然后是“KE”,从而弄乱#holder 的内容。我注意到 JQueryUI 自动完成没有这个问题,但我不明白它是如何处理的。

【问题讨论】:

  • 对于至少v1.8.17,您可以从给定的 URL,特别是第 264-267 行看到 jQuery UI 如何处理这个问题。

标签: javascript jquery jquery-ui asynchronous autocomplete


【解决方案1】:

我没有针对这个特定问题查看 jQuery 的自动完成功能,但我对自定义自动完成脚本所做的是,如果在某个时间范围内按下另一个按键,我会中止 XHR 请求。像这样的:

 var xhr, throttle;

 $('.autocomplete').keyup(function() {
      var $this = $(this);
      if (throttle)
         clearTimeout(throttle); // Clear the previous request
      xhr.abort(); // Abort the last XHR request
      throttle = setTimeout( function() {
          xhr = $.getJSON('autocomplete.php', { data: $this.val() }, function(data) {
              // do something with response
          });
      }, 250); // wait 250 milliseconds before running this
 });

基本上,节流阀确保我们在发送请求之前等待 250 毫秒,以防用户仍在键入(您可以将其设置为任何值)。 “xhr”变量将 XMLHttpRequest 保存在一个变量中,如果我们得到另一个按键并且响应还没有返回,那么我们中止前一个,确保只有最新的一个实际返回响应。

希望对您有所帮助。

祝你好运:)

【讨论】:

  • 我强烈怀疑$(this).val() 会尝试获取window 对象的值:)
  • 不客气!在我意识到你实际上可以中止 XHR 请求之前,我一直在努力解决这个问题。我的心被震撼了。 :)
【解决方案2】:

我只是在做一些非常相关的事情。一个简单的“延迟”API,用于将函数转换为延迟委托。

Function.prototype.delayed = function(ms, reset)
{
    var timeout;
    var fn = this;
    return function()
    {
        var args = arguments;
        var scope = this;
        if (reset && timeout) clearTimeout(timeout);
        timeout = setTimeout(function() { fn.apply(scope, args) }, ms);
    };
};

请参阅fiddle 了解示例使用情况。

在你的情况下是这样的

$(document).ready(function() {
    $('#textinput').live('keyup', (function() {
        $.get('bacon.php', function(data) {
            $('#holder').html(data);
        });
    }).delayed(300, true));
});

【讨论】:

    【解决方案3】:

    遇到了完全相同的问题,偶然发现了 Addy Osmani 提到的proxy pattern

    我认为它与实时观察者事件更相关

    $( "button" ).on( "click", function () {
        setTimeout( $.proxy( function () {
            // "this" now refers to our element as we wanted
            $( this ).addClass( "active" );
        }, this), 500);
    });
    

    希望有帮助

    【讨论】:

      猜你喜欢
      • 2020-05-29
      • 2012-03-14
      • 2011-08-14
      • 1970-01-01
      • 2012-10-22
      • 1970-01-01
      • 2018-09-01
      • 1970-01-01
      • 2014-01-01
      相关资源
      最近更新 更多