使用jquery列出在页面上连线的所有javascript事件
使用jQuery,是否有可能获得所有事件的列表以及事件绑定到哪个元素?
jQuery使这相对容易,因为它将事件处理程序存储在元素数据中。 你应该可以使用这样的东西:
(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);
你可以称之为:
// 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's children alert($('#myelement').eventReport()); alert($.eventReport('*', '#myelement'); // same result
更新:我添加了处理程序的计数和关于委托事件的一些信息到上述函数的输出。
更新(2012年8月24日):虽然上述function仍然在jQuery 1.7.2及更低版本中工作,但jQuery不再将事件对象存储在jQuery.data(elem, 'events')
, 如果您使用的是jQuery 1.8或更高版本你将不再能够使用上面的function!
为了交换jQuery.data(elem, 'events')
,现在可以使用jQuery._data(elem, 'events')
。 上面的函数更新如下所示:
(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()
从1.8.x http://bugs.jquery.com/ticket/9800弃用,我用;addBack()
取而代之。
// List bound events console.log($('#elem').data('events')); // Log ALL handlers for ALL events $.each($('#elem').data('events'), function(i, event) { $.each(event, function(i, handler){ console.log(handler.toString()); }); });
我使用这个列出了所有具有有界事件的元素。
$('*').each(function(){ var events = $(this).data('events'); if(events != null) { console.log(this); console.log(events); } });
也可以通过编写一些附加代码来收集元素作为每个事件的列表:
var eventArrays = {}; $('*').each(function(){ var events = $(this).data('events'); for(var anEvent in events){ if(!eventArrays[anEvent]) eventArrays[anEvent] = []; eventArrays[anEvent].push(this); } }); console.log(eventArrays);
我敢打赌,你可以遍历DOM并检查构build列表的每个元素的事件属性 …但是我从来没有尝试过。
要使用console.table()我做了一些修改…
(function($) { $.eventReport = function(selector, root) { var s = []; $(selector || '*', root).addBack().each(function() { var e = $._data(this, 'events'); if(!e) return; var tagGroup = this.tagName || "document"; if(this.id) tagGroup += '#' + this.id; if(this.className) tagGroup += '.' + this.className.replace(/ +/g, '.'); var delegates = []; for(var p in e) { var r = e[p]; var h = r.length - r.delegateCount; if(h) s.push([tagGroup, p + ' handler' + (h > 1 ? 's' : '')]); if(r.delegateCount) { for(var q = 0; q < r.length; q++) if(r[q].selector) s.push([tagGroup + ' delegates', p + ' for ' + r[q].selector]); } } }); return s; } $.fn.eventReport = function(selector) { return $.eventReport(selector, this); } })(jQuery);
所以现在我可以做这样的事情:
console.table($.eventReport())
看看chrome发生了什么事情: