55

I have a button that calls a javascript function using an event handler. For some reason, the event handler is being called twice.

Here is my button (I am using a php object to generate the code, that's why there are a lot of empty tags):

<button name="addToCart" value="" size="" onclick="" src="" class="addToCartButton" id="0011110421111" type="button" formtarget="_self" formmethod="post" formaction="" data-mini="true" width="" height="" placeholder="" data-mini="1" onkeypress="" >Add To Cart</button>

Here is my event handler:

$('.addToCartButton').click(function() {
    alert("bob");
    //addToCart($(this).attr("id"));
});

Here, I am getting the alert twice.

I have tried calling the function addToCart in the button's onclick property, but if I try it that way, I get this error:

TypeError: '[object HTMLButtonElement]' is not a function (evaluating 'addToCart(0011110421111)')

I have also tried event.preventDefault() and event.stopPropagation(), and neither worked.

Any ideas why this is happening, or what I can do to stop it from executing twice, or maybe why I am getting an error if I call the javascript function from onclick=""?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Jason247
  • 974
  • 4
  • 16
  • 38
  • 3
    You are probably calling that code that assigns the event twice! – epascarello Nov 18 '13 at 18:19
  • Why do you have so many blank attributes? – tymeJV Nov 18 '13 at 18:20
  • Do you have an onsubmit function as well somewhere? – David Nguyen Nov 18 '13 at 18:21
  • @tymeJV I am using an object that creates the button tag and just passes in values that are set. – Jason247 Nov 18 '13 at 18:24
  • @David Nguyen No, there is no onsubmit function for this button – Jason247 Nov 18 '13 at 18:25
  • 1
    What does `$._data( $(".addToCartButton")[0], "events" ).length` tell you? It should return the number of events bound to the button. – matewka Nov 18 '13 at 18:27
  • @matewka How would I use that? Do I put that in an alert inside the event handler? If so, it returned undefined, so I'm guessing that's not right. – Jason247 Nov 18 '13 at 18:34
  • 9
    My mistake. Do it that way: Open Chrome browser, go to your website, hit F12, click the `console` tab and paste this: `$._data( $(".addToCartButton")[0], "events")`. An object containing all events bound to your button will be printed to the console. The `click` property should be an array with more than one element. Expand each of them and right click on handler function. choose "Show function definition" and you should see where every handler is defined in your code. That way you should find your duplicate. – matewka Nov 18 '13 at 19:02
  • Ok, the click property has 2 elements. Both, are from the handler I have posted in my initial question above. The first one is located in the file that the function above exists (home.php). The second exists in a file that I did not create (VM237). – Jason247 Nov 18 '13 at 20:12
  • Possible duplicate of [jQuery click events firing multiple times](http://stackoverflow.com/questions/14969960/jquery-click-events-firing-multiple-times) – Heretic Monkey Mar 01 '17 at 15:50

10 Answers10

113

Maybe you are attaching the event twice on the same button. What you could do is unbind any previously set click events like this:

$('.addToCartButton').unbind('click').click(function() {
    alert("bob");
    //addToCart($(this).attr("id"));
});

This works for all attached events (mouseover, mouseout, click, ...)

Mike Vranckx
  • 5,557
  • 3
  • 25
  • 28
  • 8
    .off().on() is likely more current – mplungjan Nov 18 '13 at 18:21
  • 26
    Since this answer probably works I won't `-1` it. But I strongly discourage fixing things by _undoing_ them rather than finding the real problem and removing it. – matewka Nov 18 '13 at 18:24
  • @matewka: thanks for the suggestion, worthwhile remainder. It saved me from messing up my code. Imho, the answer did not deserve a -1 also because it points to a not-so-obvious issue that many might do: setting an event listener twice on the same object. – Giampaolo Ferradini Jan 16 '20 at 01:29
16

My event was firing twice because I accidentally included both my_scripts.js AND my_scripts.min.js. Ensure you only include one.

user1491819
  • 1,790
  • 15
  • 20
8

Unbind event from selector and after appending in element in DOM again trigger event on specific selector.. $("selector_name").unbind( "event" ); //After this call event on selector again..

For example:

$( "#button" ).unbind( "click" );

$("#button").click(function(event) {
console.log("button click again);
});
user2801665
  • 117
  • 1
  • 3
8

Just for the record in case someone else's having the same problem, I had the same issue, the root cause was that there were 3 buttons with the same ID, after clicking one, the other two also fired their OnClick events...

Gabriel G
  • 211
  • 5
  • 7
3

You probably want to pass in the event and add

$('.addToCartButton').click(function(e) {
  e.preventDefault(); //Added this
  alert("bob");
  //addToCart($(this).attr("id"));
});

OR

$('.addToCartButton').click(function(e) {
  e.preventDefault(); //Added this
  alert("bob");
  //addToCart($(this).attr("id"));
  return false;
});
Jason Snelders
  • 5,471
  • 4
  • 34
  • 40
bosspj
  • 80
  • 6
2

For me, I found out my events were not bound to my mapped component. The relevant answer is at Why is my onClick being called on render? - React.js but to provide some insights I've copied some of the answer below (Hope this helps!):

1. using .bind

activatePlaylist.bind(this, playlist.playlist_id)

2. using arrow function

onClick={ () => this.activatePlaylist(playlist.playlist_id) }

3. or return function from activatePlaylist

activatePlaylist(playlistId) {
  return function () {
     // you code 
  }
}
Kevin Danikowski
  • 4,620
  • 6
  • 41
  • 75
1

I had the same issue with my MVC project, and the problem was that I had included site.js twice; once in the _Layout.cshtml file and once in the Scripts section of the main cshtml file. Removing one solved the problem.

Amir Zare
  • 453
  • 1
  • 4
  • 15
0

For this type of error:

  • It may be that you have duplicate events bound
  • Either the event handler could be hooked up twice, or maybe the event isn't being unbound, after the intended listener(s) have finished listening and have done their job.

In this case, you need to do something to unbind the listener once you no longer need to listen.

Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206
0

I came here looking for answers. It turned out that mine wasn't exactly firing twice. It would fire, then when I later clicked something else, it would also fire for that click.

I had a container div with a click listener on it. Inside that div, a clickable link.

Clicking the link also fired the container's click event.

I spent some time with unbind('click') / rebind experiments but nothing was satisfactory. In the end I simply put a condition in the container click event so that it only ran if the click target wasn't an anchor: -

    if (e.target.tagName !== 'A') {    
        alert("bob");
        //addToCart($(this).attr("id"));
    });
cherry
  • 517
  • 5
  • 12
-1

My mistake was having a parent have the same class name as the child that i had attached the click event handler to. This caused me some confusion.

Jevon
  • 295
  • 2
  • 13