Skip to content

Instantly share code, notes, and snippets.

@chicagoworks
Created December 28, 2010 13:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chicagoworks/757206 to your computer and use it in GitHub Desktop.
Save chicagoworks/757206 to your computer and use it in GitHub Desktop.
jQuery plugin to check if elements have a given event. Updated to work with .live() and .delegate() events.
<body>
<div id="wrapper" class="great-grand-parent">
<div class="grand-parent">
<div class="parent">
<button id="foo" class="button">foo (click)</button>
<button id="bar" class="button">bar (live click)</button>
<button id="baz" class="button">baz (#wrapper delegate)</button>
</div>
</div>
</div>
<div id="other">
<div>
<button id="xxx" class="button">bar (none)</button>
<button id="yyy" class="button">foo (none)</button>
<button id="zzz" class="button">baz (none)</button>
</div>
</div>
$(document).ready(function() {
$('#foo').click(function() {
console.log('#foo click')
});
$('#bar').live('click', function barLiveClick() {
console.log('#bar live click')
});
$('#wrapper').delegate('#baz', 'click', function myDelegate() {
console.log('#baz delegate click to #wrapper')
});
});
$(window).load(function() {
console.assert($('#foo').hasEvent('click') == true);
console.assert($('#bar').hasEvent('click') == true);
console.assert($('#baz').hasEvent('click') == true);
console.assert($('#xxx').hasEvent('click') == false);
console.assert($('#foo, #bar, #baz').hasEvent('click') == true);
console.assert($('#foo, #yyy, #zzz').hasEvent('click') == true);
console.assert($('#wrapper .button').hasEvent('click') == true);
console.assert($('#other .button').hasEvent('click') == false);
console.assert($('#other').hasEvent('click') == false);
console.assert($('#wrapper').hasEvent('click') == false);
console.assert($('.button').hasEvent('click') == true);
console.assert($('.parent').hasEvent('click') == false);
console.assert($('div').hasEvent('click') == false);
console.assert($('document').hasEvent('click') == false);
console.assert($('body').hasEvent('click') == false);
});
(function($) {
$.fn.hasEvent = function(type) {
//get list of events on object
var elements = $(this), selector, evts, evt;
/*first, check for events set using $().bind('event') or $().<event>()*/
for (var x = 0; x < elements.length; x++) {
evts = $(elements).eq(x).data("events");
evt = evts && evts[type] || []; //get the events of the given type
for (var y = 0; y < evt.length; y++) {
//if no selector exists then event is normal, not a live/delegate event
if (!evt[y].selector) return true;
}
}
/*if not found on the element check for .live() events which are attached to $(document)*/
var events = jQuery.data(document, "events"), //get all events
live = events && events.live || [], //get .live events or empty array
selectors = [];
//loop thru live object, collect selectors from objects where origType matches incoming type
for (var z = 0; z < live.length; z++) {
if ((live[z].origType === type)) {
selectors.push(live[z].selector);
}
}
//check if elements match the selectors from the event handlers
//example $('#foo, #bar').is('.baz, .moo')
if (elements.is(selectors.join(','))) return true;
/*if still not found then check for .delegate() events
loop thru elements and walk heirarchy checking each parent for events*/
var pars;
live = []; //reset
selector = [];//reset
for (var i = 0; i < elements.length; i++) {
pars = $($(elements).eq(i)).parents(); //list of parent elements including self
for (var j = 0; j < pars.length; j++) {
events = $(pars[j]).data("events");
live = events && events.live || []; //any live events on parent?
for (var k = 0; k < live.length; k++) {
//if parent has a live event with a type that matches our type then grap the selector
if ((live[k].origType === type)) {
selectors.push(live[k].selector);
}
}
//var xxx = $(pars[j]).find(selectors.join(','));
//if (elements.filter(xxx).length) return true;
//console.log(elements, selectors)
if (elements.is(selectors.join(','), pars[j])) return true;
}
}
return false;
}
})(jQuery);
@chicagoworks
Copy link
Author

hasEvent plugin

Test to see if a set of jQuery objects has a given event. This plugin has been in development for a while but I recently updated to work with .live() and .delegate() events. So I decided it might be useful to others

Here are some similar plugins but I don't believe either work properly with delegates.
http://www.jamesarmes.net/plugins/jquery/hasevent

https://github.com/fate/jquery-has-event

Usage

Sample HTML

        <button id="foo">foo (bind)</button>

        <button id="bar">bar (live)</button>

        <button id="baz">baz (delegate)</button>

</div>

Attach events using bind(), .live() and .delegate

$('#foo').bind('click', function() {
    console.log('#foo click')
});

$('#bar').live('click', function barLiveClick() {
    console.log('#bar live click')
});

$('#wrapper').delegate('#baz', 'click', function myDelegate() {
    console.log('#baz delegate click to #wrapper')
});

Test for events.
$('#foo').hasEvent('click') ==> true
$('#bar').hasEvent('click') ==> true
$('#baz').hasEvent('click') ==> true
$('button').hasEvent('click') ==> true
$('#foo, #bar, #baz').hasEvent('click') ==> true
$('#wrapper .button').hasEvent('click') ==> true

Tests that properly return false. Notice the #wrapper check returns false since it a delegate for an event, not the target -- that actual target is the #baz element

$('#wrapper').hasEvent('click') ==> false
$('document').hasEvent('click') ==> false
$('div').hasEvent('click') ==> false
$('body').hasEvent('click') ==> false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment