最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery keyup Delay - Stack Overflow

programmeradmin3浏览0评论

Hopefully this is a quick and easy one for someone to figure out. I am fairly new to using a lot of javascript/jquery, and I have the following setup to pull a customer name out of a database and display it as the user has finished typing the customer ID.

All works great, but it searches at each keyup. I know I could change it to blur but I want it to search as they go, at a delay.

Here is the current code:

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

As you can see it is binding to each keyup which means that if you search too quick, it may leave you with the wrong result as it was still being loaded. (ie if no matches are found, it displays an error, and typing fast enough leaves the user needing to backspace and retype the last number)

Could someone assist in adding a delay to the existing code, and if possible a small explaination as to the change you made, I rather not just copy and paste without understanding.

---- EDIT ----

This is the code I finished up with, thank you guys!

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

Hopefully this is a quick and easy one for someone to figure out. I am fairly new to using a lot of javascript/jquery, and I have the following setup to pull a customer name out of a database and display it as the user has finished typing the customer ID.

All works great, but it searches at each keyup. I know I could change it to blur but I want it to search as they go, at a delay.

Here is the current code:

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

As you can see it is binding to each keyup which means that if you search too quick, it may leave you with the wrong result as it was still being loaded. (ie if no matches are found, it displays an error, and typing fast enough leaves the user needing to backspace and retype the last number)

Could someone assist in adding a delay to the existing code, and if possible a small explaination as to the change you made, I rather not just copy and paste without understanding.

---- EDIT ----

This is the code I finished up with, thank you guys!

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);
    });
});
Share Improve this question edited Jan 27, 2017 at 11:59 Carsten Løvbo Andersen 27k10 gold badges50 silver badges79 bronze badges asked Jan 23, 2013 at 3:17 TarquinTarquin 4922 gold badges7 silver badges21 bronze badges 1
  • 1 check this: stackoverflow.com/questions/1909441/jquery-keyup-delay – Sudhir Bastakoti Commented Jan 23, 2013 at 3:22
Add a comment  | 

4 Answers 4

Reset to default 8

You should look into the setTimeout and clearTimeout functions:

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

Basically what we're doing is that instead of firing the postData function immediately, we're passing it to setTimeout, so that it fires after a given amount of time (in this case, 300 milliseconds).

The setTimeout function returns a timer ID, which we can then pass to clearTimeout to cancel that call from ever running. On every keypress, before we set a new timer, we first check if there's a timer set. If there is, we cancel the old timer before starting a new one.


To further enhance this, you can also abort your AJAX call on every keypress, just in case the user typed something after 300+ milliseconds (after the timer fires, but before the AJAX request returned).


P.S. You should check out Ben Alman's throttle/debounce plugin, which would work perfectly here.

Take a look at Underscore's debounce function - it makes this sort of behavior super straightforward:

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

This way, the call to postData will only occur after the user has stopped typing for 500ms (or whatever you set the debounce wait to)

Also, I snuck in the input event to catch additional changes like copy/paste in addition to keystrokes (in modern browsers)

I would delay the search a bit on keyup, but you also need to abort the last request since you can't predict what order they will execute (or you can use a queue for the ajax).

I'll describe all three parts:

Delay

Wrap the postData callback in setTimeout. Store the return value of setTimeout as $("#id").data('timeout') and call clearTimeout on it each time so that the event fires only once per fast string of characters typed.

Abort

Store the last request on $("#id").data('lastRequest') or the like. Each time postData is called, run $("#id").data('lastRequest').abort(). Store the return value of $.post() in that data field. To prevent an error, initialize like this:

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

Queue

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

There might be a better way but here's something off the top of my head:

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

评论列表(0)

  1. 暂无评论