136

I setup a link element and called its click event in jQuery but the click event is calling twice, please see below the code of jQuery.

$("#link_button")
.button()
.click(function () {
   $("#attachmentForm").slideToggle("fast");
});
Syscall
  • 19,327
  • 10
  • 37
  • 52
domlao
  • 15,663
  • 34
  • 95
  • 134
  • 2
    The problem is probably from somewhere else in your script. – karim79 Jul 18 '11 at 11:04
  • 3
    if you cannot find where you made things to call this twice, make a unbind('clik') before the click(...). – regilero Jul 18 '11 at 11:08
  • regilero: exactly, the whole code base is very large. where should I put that unbind? – domlao Jul 18 '11 at 11:11
  • 2
    you can detect what functions are binding to that click event: http://stackoverflow.com/questions/570960/how-to-debug-javascript-jquery-event-bindings-with-firebug-or-similar-tool – Anh Pham Jul 18 '11 at 11:36

26 Answers26

258

Make sure and check that you have not accidentally included your script twice in your HTML page.

Scott
  • 17,127
  • 5
  • 53
  • 64
  • 1
    This was the problem for my case. That my click event was getting bubbeled. Thanks for the pointer. :) +1 – Tahir Sep 14 '11 at 08:25
  • 26
    I just looked at this solution and laughed thinking "I'm not stupid enough to do that"... turns out I had done exactly this. Thanks a lot. – JazzyP Oct 28 '14 at 10:03
  • 1
    Thanks! This turned out to be the problem for me too. Had it in a laravel blade template and in a nested template that called @parent on the same section name. Oops. Thanks again! – Phillip Harrington Oct 12 '16 at 22:07
  • 1
    Thanks for this tip. Struggled with this for over 20 hours, and this tip led me to the right path. I was using the MVC ScriptBundles but was also linking to the script files directly and this duplicated the events – Manish Apr 24 '17 at 02:21
  • lol... I've been there... I was putting the blame on the third party, but it was me who linked the .js file twice. – Julian May 22 '17 at 08:20
  • This is hilarious but another idiot here. How to debug this kind of double include? – Cyker Aug 01 '18 at 08:47
  • Hah... this was driving me up the wall. Been banging my head on my desk for an hour until I found this answer. Now I just feel dumb :P – Scott Dellinger Sep 29 '18 at 17:02
  • That was a subtle one. It also explains why the debugger was doing dumb things. Thanks. – Simon Parker Oct 12 '18 at 01:49
  • If you are using a callback to register the click handler, make sure that callback isn't being called multiple times. If it gets called more than once, you will have N-1 too many click events fired. – Alex Barker Jan 05 '19 at 00:56
  • @RajaKhoury can you please mention it was which extension, as I am similar issue, going crazy, code works fine at all the clients end except one who is using chrome. Thanks – abbas May 13 '19 at 19:13
  • @abbas I can't remember at all :( I am sorry. Did you try to disable all your extensions ? – Raja Khoury May 13 '19 at 22:47
81

Make un unbind before the click;

$("#link_button").unbind('click');
$("#link_button")
.button()
.click(function () {
   $("#attachmentForm").slideToggle("fast");
});
TheSystem
  • 1,109
  • 1
  • 7
  • 9
  • 1
    try $("#link_button").unbind(); or make a simple test to check how many times that code is read, if more than once... – TheSystem Jul 19 '11 at 10:59
  • 3
    that's just fixing the error on the fly each time, not a real solution. it does the trick and has helped me but you should find the real problem and make a permanent fix. – Juan Ignacio Oct 04 '11 at 21:50
  • 2
    it's really useful in my case, because I need to call several times the methods with my events after some ajax calls it starts to become overclicked(I don't know if this word exist). For my situation it means a solution. – Thiago C. S Ventura Oct 15 '13 at 12:08
  • Fixed my problem with a script that was only included once. Thank you! – K. Rhoda Sep 14 '17 at 15:50
  • @ThiagoC.SVentura True, I have the same situation as you said. This saved me! – Mellon Dec 06 '20 at 02:22
56

It means your code included the jquery script twice. But try this:

$("#btn").unbind("click").click(function(){

//your code

});
Nalan Madheswaran
  • 10,136
  • 1
  • 57
  • 42
42

I tried , e.stopImmediatePropagation(); This seems to work for me.

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
Aps18
  • 441
  • 6
  • 12
  • @BasheerAL-MOMANI See https://stackoverflow.com/questions/5299740/stoppropagation-vs-stopimmediatepropagation – Fangxing Jan 23 '18 at 05:24
  • Thank you, it's work... by the way after reading understand it prevent any parent handlers from being executed – Nandlal Ushir Nov 21 '19 at 10:36
  • This work for me and the following link will help to understand the function https://www.w3schools.com/jquery/event_stopimmediatepropagation.asp – muhammed fairoos nm Jun 08 '21 at 18:01
20

In my case I used the below script to overcome the issue

$('#id').off().on('click',function(){
    //...
});

off() unbinds all the events bind to #id. If you want to unbind only the click event, then use off('click').

Koopakiller
  • 2,838
  • 3
  • 32
  • 47
Upendra
  • 683
  • 6
  • 23
9

A rather common solution to the two click problem is putting

e.stopPropagation()

at the end of your function (assuming you use function(e) that is). This prevents the event from bubbling up which could lead to a second execution of the function.

demongolem
  • 9,474
  • 36
  • 90
  • 105
9

Simply call .off() right before you call .on().

This will remove all event handlers:

$(element).off().on('click', function() {
// function body
});

To only remove registered 'click' event handlers:

$(element).off('click').on('click', function() {
// function body
});
Shrinivas
  • 1,223
  • 16
  • 13
6

I had the same problem, but you can try changing this code

$("#link_button")
.button()
.click(function () {
   $("#attachmentForm").slideToggle("fast");
});

to this:

$("#link_button").button();
$("#link_button").unbind("click").click(function () {
   $("#attachmentForm").slideToggle("fast");
});

For me, this code solved the problem. But take care not to accidentally include your script twice in your HTML page. I think that if you are doing these two things correctly, your code will work correctly. Thanks

Octahedron
  • 893
  • 2
  • 16
  • 31
5

Adding e.preventDefault(); at the start of my function worked for me.

Chris Edwards
  • 3,514
  • 2
  • 33
  • 40
4

This is definitely a bug specially while it's FireFox. I searched alot tried all the above answers and finally got it as bug by many experts over SO. So, I finally came up with this idea by declaring variable like

var called = false;
$("#ColorPalete li").click(function() {
    if(!called)
    {
             called = true;
             setTimeout(function(){ //<-----This can be an ajax request but keep in mind to set called=false when you get response or when the function has successfully executed.
                 alert('I am called');
                 called = false;
             },3000);

    }
});

In this way it first checks rather the function was previously called or not.

Airy
  • 5,484
  • 7
  • 53
  • 78
3

please try this

$('#ddlSupervisor').live('change', function (e) {
    if (e.handled !== true) { //this makes event to fire only once
    getEmployeesbySupervisor();
    e.handled = true;
   }
});
Raj
  • 173
  • 1
  • 7
3

I am not sure why but I had this problem with

$(document).on("click", ".my-element", function (e) { });

When I changed it to

$(".my-element").click(function () { });

Problem was solved. But definitely something wrong in my code.

Petr
  • 1,193
  • 1
  • 15
  • 27
3

This is an older question, but if you are using event delegation this is what caused it for me.

After removing .delegate-two it stopped executing twice. I believe this happens if both delegates are present on the same page.

$('.delegate-one, .delegate-two').on('click', '.button', function() {
    /* CODE */
});
EternalHour
  • 8,308
  • 6
  • 38
  • 57
3

this snippet of code contains nothing bad. It's another part of your script as @karim told

genesis
  • 50,477
  • 20
  • 96
  • 125
2

In my case, it was working fine in Chrome and IE was calling the .click() twice. if that was your issue, then I fixed it by return false, after calling the .click() event

   $("#txtChat").keypress(function(event) {
        if (event.which == 13) {
            $('#btnChat').click();
            $('#txtChat').val('');
            return false;
        }
    });
Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
Sebastian Castaldi
  • 8,580
  • 3
  • 32
  • 24
2

Calling unbind solved my problem:

$("#btn").unbind("click").click(function() {
    // your code
});
Koopakiller
  • 2,838
  • 3
  • 32
  • 47
Deepti Gehlot
  • 617
  • 7
  • 8
2

Sure thing somewhere else in your script(s) the "click" event is being bound again to the same element, as several other answers / comments are suggesting.

I had a similar problem and in order to verify that, I simply added a console.log command to my script, like in the following snippet:

$("#link_button")
    .button()
    .click(function () {
        console.log("DEBUG: sliding toggle...");
        $("#attachmentForm").slideToggle("fast");
    });

If, upon clicking the button, you get something similar to the image below from your browser's developer console (as I did), then you know for sure that the click() event has been bound twice to the same button.

the developer's console

If you need a quick patch, the solution proposed by other commentators of using the off method (btw unbind is deprecated since jQuery 3.0) to unbind the event before (re)binding it works well, and I recommend it too:

$("#link_button")
    .button()
    .off("click")
    .click(function () {
        $("#attachmentForm").slideToggle("fast");
    });

Unfortunately, this is only a temporary patch! Once the problem of making you boss happy is resolved, you should really dig into your code a little more and fix the "duplicated binding" problem.

The actual solution depends of course on your specific use case. In my case, for example, there was a problem of "context". My function was being invoked as the result of an Ajax call applied to a specific part of the document: reloading the whole document was actually reloading both the "page" and the "element" contexts, resulting in the event being bound to the element twice.

My solution to this problem was to leverage the jQuery one function, which is the same as on with the exception that the event is automatically unbound after its first invocation. That was ideal for my use case but again, it might not be the solution for other use cases.

Sal Borrelli
  • 2,201
  • 19
  • 19
1

When I use this method on load page with jquery, I write $('#obj').off('click'); before set the click function, so the bubble not occurs. Works for me.

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
GustavoAdolfo
  • 361
  • 1
  • 9
  • 23
1

I got tricked by a selection matching multiple items so each was clicked. :first helped:

$('.someClass[data-foo="'+notAlwaysUniqueID+'"]:first').click();
Martin
  • 2,007
  • 6
  • 28
  • 44
1

I too had this issue on FF. My tag was however bound to an <a> tag. Though the <a> tag wasn't going anywhere it still did the double click. I swapped the <a> tag for a <span> tag instead and the double click issue disappeared.

Another alternative is to remove the href attribute completely if the link isn't going anywhere.

  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](http://stackoverflow.com/questions/ask). You can also [add a bounty](http://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question once you have enough [reputation](http://stackoverflow.com/help/whats-reputation). – Sean Patrick Floyd Jan 07 '15 at 22:00
  • @SeanPatrickFloyd: Actually, it is an answer. Even if formulated to raise red flags. – Deduplicator Jan 07 '15 at 22:09
1

I faced this issue because my $(elem).click(function(){}); script was placed inline in a div that was set to style="display:none;".

When the css display was switched to block, the script would add the event listener a second time. I moved the script to a separate .js file and the duplicate event listener was no longer initiated.

Zakaria Acharki
  • 66,747
  • 15
  • 75
  • 101
NRTRX
  • 161
  • 5
1

My simple answer was to turn the click bind into a function and call that from the onclick of the element - worked a treat! whereas none of the above did

Aleks G
  • 56,435
  • 29
  • 168
  • 265
Steve Whitby
  • 403
  • 4
  • 8
0

If your event is calling twice or three times, or more, this might help.

If you are using something like this to trigger events…

$('.js-someclass').click();

…then pay attention to the number of .js-someclass elements you have on the page, because it'll trigger the click event for all elements – and not just once!

A simple fix then is to make sure you trigger the click just once, by selecting just the first element, e.g.:

$('.js-someclass:first').click();
Fabien Snauwaert
  • 4,995
  • 5
  • 52
  • 70
-1

Had the same problem. This worked for me -

$('selector').once().click(function() {});

Hope this helps someone.

SGhosh
  • 857
  • 10
  • 14
  • Throws an error for me... Plus it's a dirty solution - the function is being run more than once, the solution is to place it somewhere else and use console.log() to monitor things. – tylerl May 08 '13 at 14:52
-1

In my case, the HTML was laid out like this:

<div class="share">
  <div class="wrapper">
    <div class="share">
    </div>
  </div>
</div>

And my jQuery was like this:

jQuery('.share').toggle();

It confused me because nothing appeared to be happening. The problem was that the inner .shares toggle would cancel out the outer .shares toggle.

Steven Linn
  • 696
  • 5
  • 14
-1

I solved this problem by change the element type. instead of button I place input, and this problem don't occur more.

instesd of:

<button onclick="doSomthing()">click me</button>

replace with:

<input onclick="doSomthing()" value="click me">
Shneor
  • 304
  • 3
  • 4