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
  • 37,187
  • 64
  • 214
  • 335
george
  • 4,119
  • 3
  • 17
  • 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

5 Answers5

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
  • 795,719
  • 175
  • 1,089
  • 1,143
  • 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
  • 16,281
  • 4
  • 73
  • 100
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
  • 475
  • 6
  • 9
0

Using a global variable might not be the best solution if the debounce function is used to debounce multiple functions. For that we should scope the timer to the function being denounced.

function debounce(func, timeout = 2000) {
  if (func.timer) clearTimeout(func.timer);
  func.timer = setTimeout(func, timeout);
}

debounce(func1, 4000);
debounce(func2, 1000);

NOTE: this won't work with an anonymous function;

Nafaa Boutefer
  • 2,169
  • 19
  • 26
-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