Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent calling of en event handler twice on fast clicks?

Tags:

There is a button and when user clicks on button, some data is saved to back-end. Issue is when user clicks on button very quickly, event handler is getting executed multiple times.

This is the code

var x = 1; $('#button').click(function() {   // Do something   // Save some data on network   x++;   console.log(x); }); 

I want this handler to get executed when user clicks on button just once. Even In case of double or tripple click, this should get executed only once. I just want to avoid quick clicks, this handler can get executed again ofcourse

I have multiple solutions in my mind like

  1. Define a global variable like IS_BUTTON_HANDLER_WORKING = false and when you enter the handler set it to true and in the end set it to false again. And check if it is true just return from the function.

  2. Detach the handler in the beginning and reattach in the end.

Consider you have 25 buttons in your application. What should be the best approach to implement this.

Take a look at this Fiddle

Solution

$('#button').click(function() {    $(this).attr('disabled', true);   // Do something   // Save some data on network   $(this).removeAttr('disabled'); }); 

Using this, we are sure that our next handler will get executed only when previous execution has been done completely.

like image 323
Sachin Avatar asked Nov 29 '13 08:11

Sachin


People also ask

How do you make Eventlistener work only once?

Using the once option We can pass an object as an argument to the addEventListener method and specify that the event is only handled once. This is achieved by passing the property once to the object. If we set once to true, the event will only be fired once.

Can a button have 2 event listeners?

We can add multiple event listeners for different events on the same element. One will not replace or overwrite another. In the example above we add two extra events to the 'button' element, mouseover and mouseout.

How do I stop Eventlistener?

The removeEventListener() is an inbuilt function in JavaScript which removes an event handler from an element for a attached event. for example, if a button is disabled after one click you can use removeEventListener() to remove a click event listener.


2 Answers

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);     }; }; 
like image 87
Dorad Avatar answered Oct 03 '22 15:10

Dorad


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.

like image 26
epoch Avatar answered Oct 03 '22 15:10

epoch