jQuery keyup延迟

时间:2013-01-23 03:17:43

标签: javascript jquery delay

希望这对于某人来说是一个快速而简单的方法。我使用大量的javascript / jquery是相当新的,我有以下设置从数据库中提取客户名称并在用户输入客户ID时显示它。

一切都很棒,但它会搜索每个 keyup 。我知道我可以将其更改为 blur ,但我希望它能够在延迟时进行搜索。

以下是当前代码:

function postData(){
    var id = $('#id').val();

    $.post('inc/repairs/events-backend.php',{id:id},   
        function(data){
        $("#display_customer").html(data);
    });
    return false;
}

$(function() {
    $("#id").bind('keyup',function() {postData()});
});

正如您所看到的那样,它绑定到每个keyup,这意味着如果搜索速度太快,可能会因为它仍然被加载而导致错误的结果。 (即如果没有找到匹配项,则会显示错误,并且键入足够快的速度会使用户需要退格并重新键入最后一个数字)

有人可以协助为现有代码添加延迟,如果可能的话,对您所做的更改进行一次小的解释,我不仅仅是在不理解的情况下进行复制和粘贴。

----编辑----

这是我完成的代码,谢谢你们!

function postData(){
    var id = $('#id').val();

    $.post('inc/repairs/events-backend.php',{id:id},   
        function(data){
        $("#display_customer").html(data);
    });
    return false;
}

$(function() {
    var timer;
    $("#id").bind('keyup input',function() {
        timer && clearTimeout(timer);
        timer = setTimeout(postData, 300);
    });
});

4 个答案:

答案 0 :(得分:8)

您应该查看setTimeoutclearTimeout函数:

$(function() {
    var timer;
    $("#id").on('keyup',function() {
        timer && clearTimeout(timer);
        timer = setTimeout(postData, 300);
    });
});

基本上我们正在做的是,不是立即触发postData函数,而是将它传递给setTimeout,以便在给定的时间后触发它(在这种情况下, 300毫秒)。

setTimeout函数返回一个计时器ID,我们可以将其传递给clearTimeout以取消该运行的呼叫。在每次按键时,在我们设置新计时器之前,我们首先检查是否设置了计时器。如果有,我们在开始新计时之前取消旧计时器。


为了进一步增强这一点,您还可以在每个按键上abort your AJAX call,以防万一用户在300+毫秒后输入内容(在计时器触发后,但在返回AJAX请求之前)。


P.S。你应该查看Ben Alman的throttle/debounce plugin,这在这里可以很好地运作。

答案 1 :(得分:7)

看看Underscore's debounce function - 它使这种行为变得非常简单:

$(function() {
  $('#id').on('keyup input', _.debounce(postData, 500))
}

这样,只有在用户停止输入 postData(或您设置的去抖动500ms之后)之后才会调用wait

另外,我偷偷进入the input event以捕获除了击键之外的其他更改,例如复制/粘贴(在现代浏览器中)

答案 2 :(得分:2)

我会在keyup上延迟搜索,但你还需要中止最后一个请求,因为你无法预测它们将执行的顺序(你可以使用ajax的队列)。

我将描述所有三个部分:

延迟

setTimeout中包装postData回调。将setTimeout的返回值存储为$("#id").data('timeout')并每次调用clearTimeout,以便每个快速输入的字符串只触发一次事件。

中止

将最后一个请求存储在$("#id").data('lastRequest')之类。每次调用postData时,请运行$("#id").data('lastRequest').abort()。将$.post()的返回值存储在该数据字段中。要防止出错,请按以下方式初始化:

$("#id").data('lastRequest', {abort: function () {}));

队列

$("#id").data('lastRequest', true);
...
$.when($("#id").data('lastRequest')).then(function () {
   $("#id").data('lastRequest', $.post(...));
});

答案 3 :(得分:0)

可能有更好的方法,但这里有一些不可思议的东西:

window.currentKeyup = 0;
$("#id").bind('keyup',function() {
    window.currentKeyup++;
    var keyup = window.currentKeyup;
    setTimeout(function(){
        if( keyup == window.currentKeyup ){
            postData();
        }
    },3000);
});