How to prevent calling of en event handler twice on fast clicks?
David Walsh has a great solution.
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
As per edit
You should use .one()
or
You can unbind
event on click function
var x = 1;
function myButtonClick() {
$('#button').unbind('click');
// Do something
// Save some data on network
x++;
console.log(x);
$('#button').bind('click', myButtonClick);
}
$('#button').bind('click', myButtonClick);
There are multiple ways of dealing with this:
You can disable
/hide
the button after the click:
$('#button').attr("disabled", true);
You can also set a timeout on each click to ensure it does not execute again:
var x, y = 1;
$('#button').click(function() {
if (x) clearTimeout(x);
x = setTimeout(function() {
// do the work here
y++;
console.log(y);
// ----------------
}, 1000);
});
So each time the button is clicked, it will only actually execute the code after a 1000 milliseconds
, if the button is clicked in rapid succession, the timeout will just be cleared and start over again.
note that the above is untested
Personally I think the disabled solution is the best as it indicates to the user that he has clicked and something is happening, you can even show a loader next to the button as well.