jQuery makes this relatively simple because it stores event handlers in element data. You should be able to use something like this:
(function($) { $.eventReport = function(selector, root) { var s = []; $(selector || '*', root).andSelf().each(function() { // the following line is the only change var e = $.data(this, 'events'); if(!e) return; s.push(this.tagName); if(this.id) s.push('#', this.id); if(this.className) s.push('.', this.className.replace(/ +/g, '.')); for(var p in e) { var r = e[p], h = r.length - r.delegateCount; if(h) s.push('\n', h, ' ', p, ' handler', h > 1 ? 's' : ''); if(r.delegateCount) { for(var q = 0; q < r.length; q++) if(r[q].selector) s.push('\n', p, ' for ', r[q].selector); } } s.push('\n\n'); }); return s.join(''); } $.fn.eventReport = function(selector) { return $.eventReport(selector, this); } })(jQuery);
and you can name it:
// all events alert($.eventReport()); // just events on inputs alert($.eventReport('input')); // just events assigned to this element alert($.eventReport('#myelement')); // events assigned to inputs in this element alert($.eventReport('input', '#myelement')); alert($('#myelement').eventReport('input')); // same result // just events assigned to this element children alert($('#myelement').eventReport()); alert($.eventReport('*', '#myelement'); // same result
UPDATE: I added a number of handlers and some information about delegated events to output the above function.
UPDATE (8/24/2012): Although the above function still works in jQuery 1.7.2 and below, jQuery no longer saves the event object in jQuery.data(elem, 'events') and if you use jQuery 1.8 or later, You can no longer use the function above!
In exchange for jQuery.data(elem, 'events') you can now use jQuery._data(elem, 'events') . Updating the function above will look like this:
(function($) { $.eventReport = function(selector, root) { var s = []; $(selector || '*', root).addBack().each(function() { // the following line is the only change var e = $._data(this, 'events'); if(!e) return; s.push(this.tagName); if(this.id) s.push('#', this.id); if(this.className) s.push('.', this.className.replace(/ +/g, '.')); for(var p in e) { var r = e[p], h = r.length - r.delegateCount; if(h) s.push('\n', h, ' ', p, ' handler', h > 1 ? 's' : ''); if(r.delegateCount) { for(var q = 0; q < r.length; q++) if(r[q].selector) s.push('\n', p, ' for ', r[q].selector); } } s.push('\n\n'); }); return s.join(''); } $.fn.eventReport = function(selector) { return $.eventReport(selector, this); } })(jQuery);
UPDATE (4/25/2013): andSelf() deprecated from 1.8.x http://bugs.jquery.com/ticket/9800 , I replaced addBack() instead.