george
george

Reputation: 4349

javascript/jquery - add debounce to a button

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

Upvotes: 13

Views: 31824

Answers (5)

Nafaa Boutefer
Nafaa Boutefer

Reputation: 2359

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;

Upvotes: 0

Brandon J. Boone
Brandon J. Boone

Reputation: 16472

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>

Upvotes: 14

lukejacksonn
lukejacksonn

Reputation: 485

 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 
}

Upvotes: 4

Felix Kling
Felix Kling

Reputation: 816422

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

Upvotes: 23

jzila
jzila

Reputation: 735

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

Upvotes: -4

Related Questions