سؤال

I'm building a Drop-Down menu with AJAX, and I want to delay the user query for 3 seconds before actually submitting it.

So I tried something like this:

$("#search").keyup(function(){
    clearTimeout(startcounting);
    var startcounting = setTimeout(function() {
            $.get( "mailing_search.php", { query: $("#searchitem").val() } ).done(function( data ) {
                console.log("Query Submitted");
                $("#searchbox").html(data);
            });     
        },3000);
    }
});

This doesn't work. it won't clear the timeout.
Lets say I input "samsung" it runs the query 7 times.

Any help?
Thanks in advance.

هل كانت مفيدة؟

المحلول

I think the problem is in the variable scope. You must declare startcounting outside your function.

var startcounting;
$("#search").keyup(function(){
    clearTimeout(startcounting);
    startcounting = setTimeout(function() {
        $.get( "mailing_search.php", { query: $("#searchitem").val() } ).done(function( data ) {
            console.log("Query Submitted");
            $("#searchbox").html(data);
        });     
    },3000);
}

});

نصائح أخرى

The proper way of doing it : http://jsbin.com/eqUvAYe/5/edit

You are looking for function debouncing.

function debounce(el)
{
    var exec;

  $(el).keyup(
  function ( )
    {
        if (exec)
        {
            clearTimeout(exec);
        }
        exec = setTimeout(function ()
        {
           console.log('1');     // put your ajax call here
        }, 3000);
    });

}

debounce($("#search"));

or (without wrapper function )

$("#search").keyup(
    function ()
    {
        var startcounting;
        return function ()
        {
            if (startcounting) clearTimeout(startcounting);
              startcounting = setTimeout(function ()
            {
                console.log('1') //put your ajax here.
            }, 3000);
        }
    }()
);

After reading (again ) your question , this is what you need. no need to put global variables.

FYI :

there are 2 ways for such operations :

1) throttle functions

2) function debounc.

After reading the book : Third party javascript :

there is a section there about :

Controlling expensive calls: throttle and debounce The solution to this problem lies in two techniques designed to control how often your functions are called. These techniques—throttle and debounce—work by creating a wrapper function that rate-limits calls to the original function

enter image description here

Try the following. declare the timer function outside of keyup.

startcounting = setTimeout(function() {
        $.get( "mailing_search.php", { query: $("#searchitem").val() } ).done(function( data ) {
            console.log("Query Submitted");
            $("#searchbox").html(data);
        });     
    },3000);
$("#search").keyup(function(){
    clearTimeout(startcounting);

}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top