87

I have the following problem with this code:

<button id="delete">Remove items</button>

$("#delete").button({
     icons: {
             primary: 'ui-icon-trash'
     }
}).click(function() {
     alert("Clicked");
});

If I click this button, the alert show up two times. It's not only with this specific button but with every single button I create.

What am I doing wrong?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user276289
  • 1,519
  • 2
  • 12
  • 14
  • 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:48

19 Answers19

149

In that case, we can do the following

$('selected').unbind('click').bind('click', function (e) {
  do_something();
});

I had the event firing two times initially, when the page get refreshed it fires four times. It was after many fruitless hours before I figured out with a google search.

I must also say that the code initially was working until I started using the JQueryUI accordion widget.

Simeon Abolarinwa
  • 1,632
  • 2
  • 11
  • 13
70

Your current code works, you can try it here: http://jsfiddle.net/s4UyH/

You have something outside the example triggering another .click(), check for other handlers that are also triggering a click event on that element.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 32
    You are right! I put an .unbind("click") in front of the .click(). Now it is working properly. I have to search the element that triggers the event a second time... Thank you very much! – user276289 Jun 18 '10 at 14:38
  • 1
    That sounds more like you were binding the same click event twice. jQuery will queue the bindings so if you bind several click events to the same element, when you click it, they will all fire. The slight difference would be the click event was fired twice vs the same click event bound to the element twice. – MacAnthony Jun 18 '10 at 14:43
  • 18
    @user276289 - It's possible that your code in it's entirety is running more than once, make sure it's only included one time in the page. – Nick Craver Jun 18 '10 at 14:51
  • 3
    Thanks Nick Craver! That was exactly my problem, I had my code inlined on a jQuery dialog, so it was executed again when the jQuery UI dialog was rendered. – James Sep 18 '10 at 19:53
  • 3
    Thats the correct answer. Many times, doubly loading the same JS file leads to this bug too. –  Mar 14 '13 at 04:08
  • This isn't a useful answer, or comment, but 99.99999% of the time... it's your fault. – RCNeil Mar 17 '21 at 17:48
43

Strange behaviour which I was experienced also. So for me "return false" did the trick.

$( '#selector' ).on( 'click', function() {
    //code
    return false;
});
Lukas
  • 1,699
  • 1
  • 16
  • 49
Sergey Onishchenko
  • 6,943
  • 4
  • 44
  • 51
19

If you use

$( document ).ready({ })

or

$(function() { });

more than once, the click function will trigger as many times as it is used.

Inspector Squirrel
  • 2,548
  • 2
  • 27
  • 38
nywooz
  • 351
  • 2
  • 8
17

you can try this.

    $('#id').off().on('click', function() {
        // function body
    });
    $('.class').off().on('click', function() {
        // function body
    });
reza.cse08
  • 5,938
  • 48
  • 39
9

This can as well be triggered by having both input and label inside the element with click listener.

You click on the label, which triggers a click event and as well another click event on the input for the label. Both events bubble to your element.

See this pen of a fancy CSS-only toggle: https://codepen.io/stepanh/pen/WaYzzO

Note: This is not jQuery specific, native listener is triggered 2x as well as shown in the pen.

Stepan
  • 1,136
  • 12
  • 14
9

This can be caused for following reasons:

  1. You have included the script more than once in the same html file
  2. You have added the event listener twice (eg: using onclick attribute on the element and also with jquery
  3. The event is bubbled up to some parent element. (you may consider using event.stopPropagation).
  4. If you use template inheritance like extends in Django, most probably you have included the script in more than one file which are combined together by include or extend template tags
  5. If you are using Django template, you have wrongly placed a block inside another.

So, you should either find them out and remove the duplicate import. It is the best thing to do.

Another solution is to remove all click event listeners first in the script like:

$("#myId").off().on("click", function(event) {
event.stopPropagation();
});

You can skip event.stopPropagation(); if you are sure that the event is not bubbled.

Mohammed Shareef C
  • 3,829
  • 25
  • 35
  • Thanks for including the obvious #1 in your answer. I can't believe I didn't realize that's what was going on. (facepalm) – Josh Coast Jan 04 '21 at 23:27
3

I had the same problem and tried everything but it didn't worked. So I used following trick:

function do_stuff(e)
{
    if(e){ alert(e); }
}
$("#delete").click(function() {
    do_stuff("Clicked");
});

You check if that parameter isn't null than you do code. So when the function will triggered second time it will show what you want.

kamal pal
  • 4,187
  • 5
  • 25
  • 40
Vlad Isoc
  • 2,181
  • 1
  • 15
  • 15
3
$("#id").off().on("click", function() {

});

Worked for me.

$("#id").off().on("click", function() {

});
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Shahid Hussain Abbasi
  • 2,508
  • 16
  • 10
2

Just like what Nick is trying to say, something from outside is triggering the event twice. To solve that you should use event.stopPropagation() to prevent the parent element from bubbling.

$('button').click(function(event) {
    event.stopPropagation();
});

I hope this helps.

2

in my case, i was using the change command like this way

$(document).on('change', '.select-brand', function () {...my codes...});

and then i changed the way to

$('.select-brand').on('change', function () {...my codes...});

and it solved my problem.

sh6210
  • 4,190
  • 1
  • 37
  • 27
2

Related to @Stephan's Answer.

In my case, i have both input and label in my .click() listener.

I just replaced the label to div, it worked!

Oliver Cape
  • 832
  • 10
  • 14
1

I've found that binding an element.click in a function that happens more than once will queue it so next time you click it, it will trigger as many times as the binding function was executed. Newcomer mistake probably on my end but I hope it helps. TL,DR: Make sure you bind all clicks on a setup function that only happens once.

0

Unless you want your button to be a submit button, code it as Remove items That should solve your problem. If you do not specify the type for a button element, it will default to a submit button, leading to the problem you identified.

user2672224
  • 17
  • 1
  • 3
0

If you're using AngularJS:

If you're using AngularJS and your jQuery click event is INSIDE THE CONTROLLER, it will get disturbed by the Angular's framework itself and fire twice. To solve this, move it out of the controller and do the following:

// Make sure you're using $(document), or else it won't fire.
$(document).on("click", "#myTemplateId #myButtonId", function () {
   console.log("#myButtonId is fired!");
   // Do something else.
});

angular.module("myModuleName")
   .controller("myController", bla bla bla)
Antonio Ooi
  • 1,601
  • 1
  • 18
  • 32
0

One more possibility: 2 events are different in "isTrusted" value.

I just ran into this problem. After doing a little debug, I found that the 2 events are different in "isTrusted" value.


Conditions:

I called element.click() in anotherInputBox's "keydown" event handler. After a keydown, element receive a pair of events, which one is "isTrusted:true", another is "isTrusted:false"

According to MDN (https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted), isTrusted is used to determine whether the event is user-triggered(true) or programatically-fired(false).


Solutions:

a. Handle double fire better and block the second event by state in your use case

b. Choose whether you want user-triggered or programatically-fired

c. Do not use click(). Make the click handler a function, and both call the function from event handler directly

0

I was facing the same issue got help from my mentor

$('#button_id').click($.debounce(250, function(e) {
     e.preventDefault();
     var cur = $(this);
     if ($(cur).hasClass('btn-primary')) {
          //do something
     } else {
          // do something else 
     }
 }));

myIssue when the button was clicked hasClass shows true instantly it become false and else part executed fixed by using debounce

0

Working on an old project.

I found out that when there is a radio input in the element and when the click will select the radio input, the jQuery click will be triggered twick and so it the Js

Ian 1989
  • 46
  • 3
0

I had this issue as clicking on any point on the page causes twice click event.

I checked the source code and find the cause that the jQuery library was defined twice for the final page!

  1. in the master page of the ASP.NET webform project

  2. there was a ScriptManager definition in the Application_Start event of Global.asax file.

halfer
  • 19,824
  • 17
  • 99
  • 186
Sayed Abolfazl Fatemi
  • 3,678
  • 3
  • 36
  • 48