13

I want to add a debounce to a button, but i want to perform some actions each time user clicks button, but only after 5 second after user hits button, then perform SQL update. Usually the throttle seems to be applied directly to the listener. Here I want some actions performed each time the button is clicked, and then an update after a reasonable waiting period.

I am not sure how to use the function in this case...

reference: http://code.google.com/p/jquery-debounce/

$('#myButton').click(function() {
    // do a date calculation
    // show user changes to screen
    // wait until user has has stopped clicking the 
             // button for 5 seconds, then update file with "process" function.

});

function process(){
    // update database table
}

debounce syntax

$('input').bind('keyup blur', $.debounce(process, 5000));
basickarl
  • 31,830
  • 51
  • 195
  • 300
george
  • 3,589
  • 3
  • 16
  • 18
  • So you don't know how `$.debounce` works or what is your problem? *Edit:* Ah I see.... – Felix Kling Nov 08 '11 at 19:29
  • I added details about my question. debounce and throttling is an pattern often used in ajax. Here is some good reading... http://ajaxpatterns.org/Submission_Throttling – george Nov 08 '11 at 19:32

4 Answers4

23

You could still use $.debounce like so:

// create new scope
(function() {
     // create debounced function
     var dprocess = $.debounce(process, 5000);

     // bind event handler
     $('#myButton').click(function() {
         // do a date calculation
         // show user changes to screen
         // call the function
         dprocess();
     });
}());

Alternative without $.debounce (you can always debounce your code this way, without jQuery):

// create new scope
(function() {
     var timer;

     // bind event handler
     $('#myButton').click(function() {
         if(timer) {
             clearTimeout(timer);
         }
         // do a date calculation
         // show user changes to screen
         // call the function
         timer = setTimeout(process, 5000);
     });
}());
Felix Kling
  • 756,363
  • 169
  • 1,062
  • 1,111
  • Tthis looks like the right direction. You are wrapping an anonymous function around the process? Will dprocess() be in scope when called? – george Nov 08 '11 at 19:41
  • You mean whether it will be reachable from the click event handler? Yes. I added the immediate function call so that `dprocess` does not leak into global scope. Of course you can remove this if e.g. your code is inside a `ready` event handler anyway. – Felix Kling Nov 08 '11 at 19:42
  • 1
    Very nice jQuery-less debounce example. It almost negates the need for jQuery. Almost... – Cerin May 09 '14 at 00:47
14

Debounce using native/vanilla JS and jquery/underscore.js.

Example

JS

//Native/Vanilla JS
document.getElementById('dvClickMe').onclick = debounce(function(){
    alert('clicked - native debounce'); 
}, 250);


function debounce(fun, mil){
    var timer; 
    return function(){
        clearTimeout(timer); 
        timer = setTimeout(function(){
            fun(); 
        }, mil); 
    };
}

//jQuery/Underscore.js
$('#dvClickMe2').click(_.debounce(function(){
    alert('clicked - framework debounce'); 
}, 250)); 

HTML

<div id='dvClickMe'>Click me fast! Native</div>
<div id='dvClickMe2'>Click me fast! jQuery + Underscore</div>
Brandon Boone
  • 15,753
  • 4
  • 73
  • 96
4
 var timer;
 $('#myButton').click(function() {
     //Called every time #myButton is clicked         
     if(timer) clearTimeout(timer);
     timer = setTimeout(process, 5000);
 });

function process(){
  //Called 5000ms after #myButton was last clicked 
}
lukejacksonn
  • 465
  • 6
  • 9
-4

Why not just use setTimeOut(function() { process(); }, 5000);

jzila
  • 724
  • 4
  • 11
  • As I understand, this just adds a delay. I want to ignore initial clicks and then just run update when user has calmed down for a few seconds. – george Nov 08 '11 at 19:39
  • Fair enough. You could implement that similarly without debounce, but it seems like that is probably the way to go. – jzila Nov 08 '11 at 19:48