How to check if click event is already bound - JQuery

Jquery

Jquery Problem Overview


I am binding a click event with a button:

$('#myButton').bind('click',  onButtonClicked);

In one scenario, this is getting called multiple times, so when I do a trigger I see multiple ajax calls which I want to prevent.

How do I bind only if its not bound before.

Jquery Solutions


Solution 1 - Jquery

One more way - mark such buttons with a CSS class and filter:

$('#myButton:not(.bound)').addClass('bound').bind('click',  onButtonClicked);

In recent jQuery versions replace bind with on:

$('#myButton:not(.bound)').addClass('bound').on('click',  onButtonClicked);

Solution 2 - Jquery

Update 24 Aug '12: In jQuery 1.8, it is no longer possible to access the element's events using .data('events'). (See this bug for details.) It is possible to access the same data with jQuery._data(elem, 'events'), an internal data structure, which is undocumented and therefore not 100% guaranteed to remain stable. This shouldn't, however, be a problem, and the relevant line of the plugin code above can be changed to the following:

var data = jQuery._data(this[0], 'events')[type];

jQuery events are stored in a data object called events, so you could search in this:

var button = $('#myButton');
if (-1 !== $.inArray(onButtonClicked, button.data('events').click)) {
    button.click(onButtonClicked);
}

It would be best, of course, if you could structure your application so this code only gets called once.


This could be encapsulated into a plugin:

$.fn.isBound = function(type, fn) {
    var data = this.data('events')[type];

    if (data === undefined || data.length === 0) {
        return false;
    }

    return (-1 !== $.inArray(fn, data));
};

You could then call:

var button = $('#myButton');
if (!button.isBound('click', onButtonClicked)) {
    button.click(onButtonClicked);
}

Solution 3 - Jquery

If using jQuery 1.7+:

You can call off before on:

$('#myButton').off('click', onButtonClicked) // remove handler
              .on('click', onButtonClicked); // add handler

If not:

You can just unbind it first event:

$('#myButton').unbind('click', onButtonClicked) //remove handler
              .bind('click', onButtonClicked);  //add handler

Solution 4 - Jquery

The best way I see is to use live() or delegate() to capture the event in a parent and not in each child element.

If your button is inside a #parent element, you can replace:

$('#myButton').bind('click', onButtonClicked);

by

$('#parent').delegate('#myButton', 'click', onButtonClicked);

even if #myButton doesn't exist yet when this code is executed.

Solution 5 - Jquery

I wrote a very tiny plugin called "once" which do that. Execute off and on in element.

$.fn.once = function(a, b) {
    return this.each(function() {
        $(this).off(a).on(a,b);
    });
};

And simply:

$(element).once('click', function(){
});

Solution 6 - Jquery

Why not use this

unbind() before bind()

$('#myButton').unbind().bind('click',  onButtonClicked);

Solution 7 - Jquery

Here's my version:

Utils.eventBoundToFunction = function (element, eventType, fCallback) {
    if (!element || !element.data('events') || !element.data('events')[eventType] || !fCallback) {
        return false;
    }

    for (runner in element.data('events')[eventType]) {
        if (element.data('events')[eventType][runner].handler == fCallback) {
            return true;
        }

    }

    return false;
};

Usage:

Utils.eventBoundToFunction(okButton, 'click', handleOkButtonFunction)

Solution 8 - Jquery

To avoid to check/bind/unbind, you can change your approach! Why don't you use Jquery .on() ?

Since Jquery 1.7, .live(), .delegate() is deprecated, now you can use .on() to

> Attach an event handler for all elements which match the current selector, now and in the future

It means that you can attach an event to a parent element that is still existing and attach children elements whether they are present or not!

When you use .on() like this:

$('#Parent').on('click', '#myButton'  onButtonClicked);

You catch event click on parent and it search child '#myButton' if exists...

So when you remove or add a child element, you do not have to worry about whether to add or remove the event binding.

Solution 9 - Jquery

Based on @konrad-garus answer, but using data, since I believe class should be used mostly for styling.

if (!el.data("bound")) {
  el.data("bound", true);
  el.on("event", function(e) { ... });
}

Solution 10 - Jquery

Try:

if (typeof($("#myButton").click) != "function") 
{
   $("#myButton").click(onButtonClicked);
}

Solution 11 - Jquery

if ($("#btn").data('events') != undefined && $("#btn").data('events').click != undefined) {
    //do nothing as the click event is already there
} else {
    $("#btn").click(function (e) {
        alert('test');
    });
}

Solution 12 - Jquery

As of June 2019, I've updated the function (and it's working for what I need)

$.fn.isBound = function (type) {
    var data = $._data($(this)[0], 'events');

    if (data[type] === undefined || data.length === 0) {
        return false;
    }
    return true;
};

Solution 13 - Jquery

JQuery has solution:

$( "#foo" ).one( "click", function() {
  alert( "This will be displayed only once." );
}); 

equivalent:

$( "#foo" ).on( "click", function( event ) {
  alert( "This will be displayed only once." );
  $( this ).off( event );
});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDustyView Question on Stackoverflow
Solution 1 - JqueryKonrad GarusView Answer on Stackoverflow
Solution 2 - JquerylonesomedayView Answer on Stackoverflow
Solution 3 - JqueryNaftaliView Answer on Stackoverflow
Solution 4 - JqueryPabloneteView Answer on Stackoverflow
Solution 5 - JqueryRodolfo Jorge Nemer NogueiraView Answer on Stackoverflow
Solution 6 - JqueryKrillehbgView Answer on Stackoverflow
Solution 7 - JqueryYair GallerView Answer on Stackoverflow
Solution 8 - JqueryA. MorelView Answer on Stackoverflow
Solution 9 - JqueryarielView Answer on Stackoverflow
Solution 10 - JqueryMukhtiar ZaminView Answer on Stackoverflow
Solution 11 - JqueryBishoy HannaView Answer on Stackoverflow
Solution 12 - JqueryCarlos CasalicchioView Answer on Stackoverflow
Solution 13 - JqueryVeniaminView Answer on Stackoverflow