Используя jQuery, можно ли получить список всех событий и к какому элементу привязано событие?
Список всех событий javascript, подключенных к странице с помощью jquery
Ответ 1
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 children
alert($('#myelement').eventReport());
alert($.eventReport('*', '#myelement'); // same result
UPDATE: Я добавил количество обработчиков и некоторую информацию о делегированных событиях для вывода вышеуказанной функции.
ОБНОВЛЕНИЕ (8/24/2012):
Хотя вышеприведенная функция все еще работает в jQuery 1.7.2 и ниже, jQuery больше не сохраняет объект события в jQuery.data(elem, 'events')
и , если вы используете jQuery 1.8 или новее, вы больше не сможете использовать функцию выше!
В обмен на 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);
ОБНОВЛЕНИЕ (4/25/2013):
andSelf()
устарел от 1.8.x http://bugs.jquery.com/ticket/9800, вместо этого я заменил addBack()
.
Ответ 2
вы можете проверить этот инструмент http://www.sprymedia.co.uk/article/Visual+Event+2
Ответ 3
// 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());
});
});
Ответ 4
Я использую этот список для отображения всех элементов с ограниченным событием.
$('*').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);
Ответ 5
Бьюсь об заклад, вы можете пересечь DOM и проверить событие attribute для каждого элемента, создающего список... но я ' никогда не пробовал.
Ответ 6
Чтобы использовать 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())
Посмотрите, что происходит на хроме: