Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery .click being called multiple times

Tags:

jquery

I am getting unexpected results with jQuery trying to set the "click" method of a div. Please see this jsfiddle. Be sure to open the console window. Click the word a few times and watch the console output. The click function gets called multiple times when it should only be called once.

The commented out code at the end works just fine. Am I doing something wrong? I'm new to jQuery.

Here's the code:

function toggleDiv(status)
{
    console.log("toggleDiv(" + status + ")");
    if (status) {
        $("#test").html("Goodbye");
    }
    else  {
        $("#test").html("Hello");
    }
    $("#test").click(function() {
        toggleDiv(!status);
    });

    // Non-jquery method works fine....
    //document.getElementById("test").onclick = function () {
    //    toggleDiv(!status);
    //}
}​

Update: looks like there are lots of ways to skin this cat. The real issue here was my not understanding that the jQuery "click" functions ADDS another handler. I thought it REPLACED the current handler.

like image 966
Johnny Mopp Avatar asked Aug 23 '12 14:08

Johnny Mopp


People also ask

Why is this jQuery Ajax click event firing multiple times?

an Event will fire multiple time when it is registered multiple times (even if to the same handler).

How do you make a button click only once in jQuery?

jQuery one() Method When using the one() method, the event handler function is only run ONCE for each element.

What is the difference between .click and .on (' click in jQuery?

on() differs from . click() in that it has the ability to create delegated event handlers by passing a selector parameter, whereas . click() does not.

What is unbind in jQuery?

The unbind() method removes event handlers from selected elements. This method can remove all or selected event handlers, or stop specified functions from running when the event occurs. This method can also unbind event handlers using an event object.


2 Answers

The jQuery click function doesn't overwrite a previous click handler but instead adds the new one to a queue. So when click is called again, a new click handler is added along with all the old ones.

To prevent this, you just need to clear the old handlers before defining your new one.

function toggleDiv(status)
{
    console.log("toggleDiv(" + status + ")");
    if (status) {
        $("#test").html("Goodbye");
    }
    else  {
        $("#test").html("Hello");
    }

    $("#test").unbind();

    $("#test").click(function() {
        toggleDiv(!status);
    });
}​

You may also want to look at the .toggle() event handler.

UPDATE: To be clearer about .toggle(), this will also do what you want:

$("#test").toggle(
    function(event) { $(event.target).html("Goodbye"); },
    function(event) { $(event.target).html("Hello"); }
);
like image 65
Joseph Erickson Avatar answered Sep 19 '22 11:09

Joseph Erickson


You are setting a new .click() eventHandler each time you keep clicking it (which in turn creates even more events). On a side note, try to never use onclick / onmouseover / onmouseout / etc events on DOM elements. In Internet explorer these create script blocks (that you can visibly see if you use Visual Studio. Pages with thousands of these slow down performance tremendously!

It looks like you are trying to achieve this:

jsFiddle DEMO

$("#test").on('click', function() {
    var this$   = $(this),
        _status = !!this$.data('status'); // force to boolean
                  // ^will default to false since we have no data-status attribute yet

    this$.html(_status ? 'Hello' : 'Goodbye')
         .data('status', !_status);
});​
like image 24
Mark Pieszak - Trilon.io Avatar answered Sep 18 '22 11:09

Mark Pieszak - Trilon.io