web-dev-qa-db-fra.com

Répertoriez tous les événements javascript reliés à une page à l'aide de jquery

Avec jQuery, est-il possible d’obtenir une liste de tous les événements et de l’élément auquel l’événement est lié?

45
moomoo

jQuery rend cela relativement facile car il stocke les gestionnaires d'événements dans les données d'élément. Vous devriez pouvoir utiliser quelque chose comme ceci:

(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);

et vous pouvez l'appeler:

// 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

UPDATE: J'ai ajouté un nombre de gestionnaires et des informations sur les événements délégués à la sortie de la fonction ci-dessus.

UPDATE (24/08/2012): Bien que la fonction ci-dessus fonctionne toujours dans jQuery 1.7.2 et versions antérieures, jQuery ne stocke plus l'objet événement dans jQuery.data(elem, 'events') et si vous utilisez jQuery 1.8 ou une version ultérieure vous ne pourrez plus utiliser la fonction ci-dessus!

En échange de jQuery.data(elem, 'events'), vous pouvez maintenant utiliser jQuery._data(elem, 'events'). Une mise à jour de la fonction ci-dessus ressemblerait à ceci:

(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 (25/04/2013):andSelf() est obsolète depuis la version 1.8.x http://bugs.jquery.com/ticket/9800 , j'ai remplacé par addBack() à la place.

92
Prestaul
6
Mina W Alphonce
// 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());
  });
});
5
Misha Moroshko

J'utilise celui-ci pour lister tous les éléments qui ont un événement borné.

$('*').each(function(){
    var events = $(this).data('events');
    if(events != null)
    {
        console.log(this);
        console.log(events);
    }
});

Il est également possible de collecter des éléments sous forme de liste pour chaque événement en écrivant des codes supplémentaires tels que:

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);
3

Pour utiliser console.table (), j'ai fait quelques modifications ... 

(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);

Alors maintenant, je peux faire des choses comme ça:

console.table($.eventReport())

Voyez ce qui se passe chez Chrome: Console in chrome

0
Rodolpho Brock

Je parie que vous pourriez parcourir le DOM et inspecter l'événement attribut de chaque élément constituant une liste ... mais je ne l'ai jamais essayé.

0
Tom Ritter