【问题标题】:Sending jQuery ajax request on keyboard input在键盘输入上发送 jQuery ajax 请求
【发布时间】:2013-01-12 05:16:53
【问题描述】:

我在用户输入 <input> 元素时向服务器发送 ajax 请求,如下所示:

$('#my-input').bind("input", function(event){
   // here's the ajax request
});

困扰我的是它在每个用户的keyup上发送了不必要的许多请求,这意味着如果用户键入非常快,就会有许多不必要的请求。所以我认为应该有一定的延迟/超时,等待一定的时间(50 毫秒?)让用户在发送 ajax 请求之前停止输入。这样就解决了一个问题。

但是在发送另一个请求之前第一个 ajax 请求还没有完成的情况呢? (键入 60 毫秒/字符,而 ajax 请求需要 300 毫秒)。

解决这个问题的最佳方法是什么(基于想法和代码)?

【问题讨论】:

  • 您是想捕捉每一次击键,还是只想捕捉结束信息(模糊)?
  • @sgeddes:我不想要每次捕获,我想要结束消息,但最后没有模糊(用户不必取消单击该区域)。
  • 只有捕获输入选项吗?或忽略退格 - 不知道这是否真的有很大帮助

标签: javascript jquery ajax


【解决方案1】:

您可以在下划线库中使用throttle 函数。正如其文档所述:

创建并返回传递函数的一个新的、受限制的版本,当重复调用时,每等待毫秒最多只会实际调用一次原始函数。对于发生速度快于您跟不上的限速事件很有用。

即使您不想引入新库,您仍然可以从其source code 中了解此函数的工作原理。事实上,throttle 函数的简单版本可以是:

function throttle(func, delay) {
    var timeout = null;
    return function() {
        var that = this, args = arguments;
        clearTimeout(timer);
        timeout = setTimeout(function() {
            func.apply(that, args);
        }, delay);
    };
}

这个 jQuery throttle-debounce plugin 也很有帮助。特别是,根据作者的说法,debounce 函数似乎比 throttle 函数更适合您的需求:

去抖动对于限制将触发 AJAX 请求的事件的处理程序执行速率特别有用

【讨论】:

  • 我认为这不是解决此问题的最佳方法。图书馆对我来说似乎非常不必要。
  • 如果你大量使用 JS,这个库是你的好朋友。无论如何,您可以从其源代码中获取代码 sn-p。
  • 但是当 jQuery 提供 setTimeout 时,为什么要引入一个新库呢?节流似乎不适合这种情况...
  • @sgeddes 首先,setTimeout 是 JS 内置函数,不是 jQuery 特有的。其次,正如我所说,您不必引入新库,该功能实现不长,只需复制粘贴即可。最后,我更新了我的答案并建议了另一个库,debounce 可能比throttle 更合适。
【解决方案2】:

您可以只使用 setTimeout 函数。每隔一段时间,看看文本是否没有改变,如果没有,则进行相应的处理。

setTimeout(function() {
      // Do something after 1 second
}, 1000);

【讨论】:

  • 是的,这解决了问题的第一部分,但不是覆盖 ajax 请求。
  • 这可能是您必须在服务器端解决的问题。在提交到数据库之前排队请求。有几种不同的实现。
【解决方案3】:

您可以在您的 ajax 请求中设置 async: false,这样它只会在第一个 ajax 请求完成后处理第二个 ajax 调用。

【讨论】:

    【解决方案4】:

    我会选择@HuiZeng's answer,但以防万一您想要稍微修改的版本。

    步骤

    1. 使用可以清除的 setTimeout 收听 keydown。
    2. 当它触发时,检查队列中是否有先前的请求,如果有则中止它并触发新的请求

    例子:

    var inputTimer = 0, req;
    
    function onInput(e){
          clearTimeout(inputTImer);
          inputTimer = setTimeout( function(){
               // You have access to e here
               // Cancel any previous requests
               req && req.abort();
               req = $.ajax({/*...Do your magic here :)*/})
          }, 100)
     }
    

    【讨论】:

      猜你喜欢
      • 2015-06-05
      • 2017-01-14
      • 1970-01-01
      • 2016-07-25
      • 1970-01-01
      • 2012-07-11
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多