tags:

views:

42

answers:

2

Is there a way to list all elements that contain two or more events of the same kind?

I put a little example at JsBin: http://jsbin.com/alafo3/edit

In this example I want a list that contains the <p> with ID="hallo2".

+2  A: 

You can loop over the $.cache object where events are stored, like this:

$.each($.cache, function(i, v) {
  if(v.events && v.events.click && v.events.click.length > 1) {
    alert($('[' + $.expando + '=' + i + ']').attr('id'));
  }
})​;

Give it a try here, or make it more generic for any event with multiple handlers, like this:

$.each($.cache, function(i, v) {
  $.each(v.events, function(j, u) {
    if(u.length > 1)
      alert($('[' + $.expando + '=' + i + ']').attr('id'));
  });
})​;

You can try that version here, Note that both of these approaches needs jQuery 1.4+, the expando property isn't exposed in 1.3.x.


If you want a jQuery collection referring to these elements, you can build it as you go, like this:

var elems = [];
$.each($.cache, function(i, v) {
  $.each(v.events, function(j, u) {
    if(u.length > 1)
      $.merge(elems, $('[' + $.expando + '=' + i + ']'));
  });
});
​$(elems).css('color', 'red');​​​​ //use it, $(DOMElementArray) overload here

You can test that version here.

Nick Craver
@downvoter - It helps to explain what you think is incorrect. If you have knowledge that would improve the answer for future viewers it's best to share it.
Nick Craver
+3  A: 

You can also access the events key of the attached data, e.g.

$('#hello2').data('events').click.length

returns 2.

Update:

You could for example extend jQuery this way:

$.fn.hasMultipleEventHandlersFor = function(event) {
    return this.filter(function() {
        var events =  $(this).data('events');
        return events && events[event] && events[event].length > 1;
    });
};

And use it like:

$('p').hasMultipleEventHandlersFor('click');

which will select all elements that have multiple handlers for the click event.

Felix Kling