test if event handler is bound to an element in jQuery [duplicate]


Is it possible to determine whether an element has a click handler, or a change handler, or any kind of event handler bound to it using jQuery?

Furthermore, is it possible to determine how many click handlers (or whatever kind of event handlers) it has for a given type of event, and what functions are in the event handlers?

You can get this information from the data cache.

For example, log them to the console (firebug, ie8):

console.dir( $('#someElementId').data('events') );

or iterate them:

jQuery.each($('#someElementId').data('events'), function(i, event){

    jQuery.each(event, function(i, handler){

        console.log( handler.toString() );

    });

});

Another way is you can use the following bookmarklet but obviously this does not help at runtime.


Killing off the binding when it does not exist yet is not the best solution but seems effective enough! The second time you ‘click’ you can know with certainty that it will not create a duplicate binding.

I therefore use die() or unbind() like this:

$("#someid").die("click").live("click",function(){...

or

$("#someid").unbind("click").bind("click",function(){...

or in recent jQuery versions:

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

I wrote a plugin called hasEventListener which exactly does that :

http://github.com/sebastien-p/jquery.hasEventListener

Hope this helps.


This solution is no more supported since jQuery 1.8 as we can read on the blog here:

$(element).data(“events”): This is now removed in 1.8, but you can still get to the events data for debugging purposes via $._data(element, "events"). Note that this is not a supported public interface; the actual data structures may change incompatibly from version to version.

So, you should unbind/rebind it or simply, use a boolean to determine if your event as been attached or not (which is in my opinion the best solution).


I think this might have updated with jQuery 1.9.*

I'm finding the this is the only thing that works for me at the moment:

$._data($("#yourElementID")[0]).events

I wrote a very tiny plugin called "once" which do that:

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

And simply:

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

For jQuery 1.9+

var eventListeners = $._data($('.classname')[0], "events");

I needed the [0] array literal.


I don't think that the hasEventListener plugin mentioned will handle custom events e.g.

var obj = {id:'test'};
$(obj).bind('custom', function(){
    alert('custom');
}).trigger('custom');

alert($(obj).hasEventListener('custom'));

Also, at least in jQuery 1.5 I think you need to be careful using $(target).data('events') because it returns differently for events that have been bound to objects as above.

You need to do something like:

var events = $(target).data("events");
if(typeof events === "function"){
   events = events.events;
}

I am using this sort of approach and it works but it feels a bit like I am at the mercy of jquery internals and that really I shouldn't be doing it!


I had the same need & quickly patched an existing code to be able to do something like this:

 if( $('.scroll').hasHandlers('mouseout') )  // could be click, or '*'...
 { 
   ... code ..
 }

It works for event delegation too:

 if ( $('#main').hasHandlers('click','.simple-search') )  ...

It is available here : jquery-handler-toolkit.js


With reference to SJG's answer and from W3Schools.com

As of jQuery version 1.7, the off() method is the new replacement for the unbind(), die() and undelegate() methods. This method brings a lot of consistency to the API, and we recommend that you use this method, as it simplifies the jQuery code base.

This gives:

$("#someid").off("click").live("click",function(){...

or

$("#someid").off("click").bind("click",function(){...

This works for me: $('#profile1').attr('onclick')