Список всех событий javascript, подключенных к странице с помощью jquery

Используя 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().

Ответ 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())

Посмотрите, что происходит на хроме: Console in chrome