Comment déboguer les liaisons d'événements JavaScript / jQuery avec Firebug ou des outils similaires?

609

J'ai besoin de déboguer une application Web qui utilise jQuery pour effectuer des manipulations DOM assez complexes et compliquées . À un moment donné, certains des événements liés à des éléments particuliers ne sont pas déclenchés et cessent simplement de fonctionner.

Si j'avais la capacité de modifier la source de l'application, j'explorerais et ajouterais un tas d' instructions Firebug console.log() et commenter / décommenter des morceaux de code pour essayer d'identifier le problème. Mais supposons que je ne puisse pas modifier le code de l'application et que je doive travailler entièrement dans Firefox en utilisant Firebug ou des outils similaires.

Firebug est très bon pour me laisser naviguer et manipuler le DOM. Jusqu'à présent, cependant, je n'ai pas pu comprendre comment déboguer les événements avec Firebug. Plus précisément, je veux juste voir une liste de gestionnaires d'événements liés à un élément particulier à un moment donné (en utilisant des points d'arrêt JavaScript Firebug pour suivre les modifications). Mais soit Firebug n'a pas la capacité de voir les événements liés, soit je suis trop stupide pour le trouver. :-)

Des recommandations ou des idées? Idéalement, je voudrais juste voir et éditer des événements liés à des éléments, de la même manière que je peux éditer DOM aujourd'hui.

Jaanus
la source

Réponses:

355

Voir Comment trouver des écouteurs d'événements sur un nœud DOM .

En bref, en supposant qu'à un moment donné, un gestionnaire d'événements est attaché à votre élément (par exemple): $('#foo').click(function() { console.log('clicked!') });

Vous l'inspectez ainsi:

  • jQuery 1.3.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, value) {
      console.log(value) // prints "function() { console.log('clicked!') }"
    })
  • jQuery 1.4.x

    var clickEvents = $('#foo').data("events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
      console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })

Voir jQuery.fn.data(où jQuery stocke votre gestionnaire en interne).

  • jQuery 1.8.x

    var clickEvents = $._data($('#foo')[0], "events").click;
    jQuery.each(clickEvents, function(key, handlerObj) {
      console.log(handlerObj.handler) // prints "function() { console.log('clicked!') }"
    })
Croissant frais
la source
21
FYI: Cela n'affichera pas les événements qui n'étaient pas attachés avec jQuery
Juan Mendes
10
Tout à fait d'accord sur console.log (), mais il devrait être couvert avec quelque chose comme if (window.console)au cas où il resterait dans le code (beaucoup plus facile à faire qu'avec alert ()) et casse IE.
thepeer
14
@thepeer Personnellement, je préfère faire une vérification de la console au début du fichier, et s'il n'existe pas, créer un objet factice.
Andrew
Ci-dessous, un extrait similaire pour le débogage de tous les événements (veuillez excuser le manque de formatage):$('#foo').click(function(event) { var events = $(this).data('events'); $.each(events, function(event, handlers) { $.each(handlers, function(key, handlerObj) { console.log("--------------------------------------"); console.log(event+"["+key+"] | "+handlerObj.handler) ; }); });
Corey O.
3
@ BrainSlugs83: voir la réponse liée dans cette réponse. (tl; dr: vous ne pouvez pas).
Crescent Fresh du
162

Il y a un joli bookmarklet appelé Visual Event qui peut vous montrer tous les événements attachés à un élément. Il a des reflets codés par couleur pour différents types d'événements (souris, clavier, etc.). Lorsque vous les survolez, il affiche le corps du gestionnaire d'événements, comment il a été attaché et le numéro de fichier / ligne (sur WebKit et Opera). Vous pouvez également déclencher l'événement manuellement.

Il ne peut pas trouver tous les événements car il n'existe aucun moyen standard de rechercher les gestionnaires d'événements attachés à un élément, mais il fonctionne avec les bibliothèques populaires comme jQuery, Prototype, MooTools, YUI, etc.

Matthew Crumley
la source
8
Notez que puisque cela s'exécute dans le contenu JavaScript, il obtient ses données en interrogeant les bibliothèques JavaScript. Il n'affichera donc que les événements ajoutés avec une bibliothèque prise en charge (qui inclut jQuery).
Matthew Flaschen
41

Vous pouvez utiliser FireQuery . Il montre tous les événements attachés aux éléments DOM dans l'onglet HTML de Firebug. Il montre également toutes les données attachées aux éléments via $.data.

Shrikant Sharat
la source
1
Ce plugin a 1 très gros inconvénient: lorsque vous déboguez et que vous souhaitez inspecter la valeur d'une variable qui contient une collection jquery, vous ne pouvez pas inspecter la valeur lorsque votre code est en pause. Ce n'est pas la cause de Firebug. La raison pour laquelle je l'ai désinstallé. seul
Maarten Kieft
1
FireQuery ne semble plus afficher les événements attachés :(
Matty J
26

Voici un plugin qui peut répertorier tous les gestionnaires d'événements pour un élément / événement donné:

$.fn.listHandlers = function(events, outputFunction) {
    return this.each(function(i){
        var elem = this,
            dEvents = $(this).data('events');
        if (!dEvents) {return;}
        $.each(dEvents, function(name, handler){
            if((new RegExp('^(' + (events === '*' ? '.+' : events.replace(',','|').replace(/^on/i,'')) + ')$' ,'i')).test(name)) {
               $.each(handler, function(i,handler){
                   outputFunction(elem, '\n' + i + ': [' + name + '] : ' + handler );
               });
           }
        });
    });
};

Utilisez-le comme ceci:

// List all onclick handlers of all anchor elements:
$('a').listHandlers('onclick', console.info);

// List all handlers for all events of all elements:
$('*').listHandlers('*', console.info);

// Write a custom output function:
$('#whatever').listHandlers('click',function(element,data){
    $('body').prepend('<br />' + element.nodeName + ': <br /><pre>' + data + '<\/pre>');
});

Src: (mon blog) -> http://james.padolsey.com/javascript/debug-jquery-events-with-listhandlers/

James
la source
11

Utilisation $._data(htmlElement, "events") dans jquery 1.7+;

ex:

$._data(document, "events") ou $._data($('.class_name').get(0), "events")

Tamás Pap
la source
8

Comme l'a suggéré un collègue, console.log> alert:

var clickEvents = $('#foo').data("events").click;
jQuery.each(clickEvents, function(key, value) {
    console.log(value);
})
Flevour
la source
6

jQuery stocke les événements dans les éléments suivants:

$("a#somefoo").data("events")

Faire un console.log($("a#somefoo").data("events"))devrait lister les événements attachés à cet élément.

Alex Heyd
la source
5

En utilisant DevTools dans la dernière version de Chrome (v29), je trouve ces deux conseils très utiles pour le débogage d'événements:

  1. Liste des événements jQuery du dernier élément DOM sélectionné

    • Inspecter un élément sur la page
    • tapez ce qui suit dans la console:

      $ ._ data ( $ 0 , "events") // en supposant que jQuery 1.7+

    • Il répertorie tous les objets d'événement jQuery qui lui sont associés, développe l'événement intéressé, fait un clic droit sur la fonction de la propriété "handler" et choisit "Afficher la définition de la fonction". Il ouvrira le fichier contenant la fonction spécifiée.

  2. Utilisation de la commande monitorEvents ()

mateuscb
la source
4

Il semble que l'équipage de FireBug travaille sur une extension EventBug. Il ajoutera un autre panneau à FireBug - Events.

"Le panneau des événements répertorie tous les gestionnaires d'événements sur la page regroupés par type d'événement. Pour chaque type d'événement, vous pouvez ouvrir pour voir les éléments auxquels les écouteurs sont liés et un résumé de la source de la fonction." EventBug Rising

Bien qu'ils ne puissent pas dire pour l'instant quand il sera publié.

jayarjo
la source
2
Cette fonctionnalité a été publiée et incluse dans FireBug 2.0.1. Maintenant, lorsque vous inspectez un élément HTML sur une page, il y a un nouveau panneau "Événements" où vous pouvez voir les événements attachés et leurs gestionnaires.
derloopkat
4

J'ai également trouvé jQuery Debugger dans la boutique Chrome. Vous pouvez cliquer sur un élément dom et il affichera tous les événements qui lui sont liés ainsi que la fonction de rappel. Je déboguais une application où les événements n'étaient pas supprimés correctement et cela m'a aidé à la retrouver en quelques minutes. Évidemment, c'est pour Chrome, pas pour Firefox.

Rob
la source
4

ev icône à côté des éléments

Dans le panneau Inspecteur des outils pour développeurs Firefox , répertorie tous les événements liés à un élément.

Sélectionnez d'abord un élément avec Ctrl+ Shift+ C, par exemple la flèche vers le haut de Stack Overflow.

Cliquez sur l' evicône à droite de l'élément et une boîte de dialogue s'ouvre:

info-bulle des événements

Cliquez sur le ||symbole de signe de pause pour l'événement que vous voulez, et cela ouvre le débogueur sur la ligne du gestionnaire.

Vous pouvez maintenant y placer un point d'arrêt comme d'habitude dans le débogueur, en cliquant sur la marge gauche de la ligne.

Ceci est mentionné sur: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_event_listeners

Malheureusement, je n'ai pas pu trouver un moyen de bien jouer avec prettyfication, il semble juste s'ouvrir à la ligne minifiée: Comment embellir Javascript et CSS dans Firefox / Firebug?

Testé sur Firefox 42.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Malheureusement, cela ne fonctionne pas bien pour localiser les auditeurs hérités.
chukko
3

Selon ce fil , il n'y a aucun moyen dans Firebug de voir quels événements sont attachés aux écouteurs sur un élément DOM.

Il semble que le mieux que vous puissiez faire est soit ce que suggère tj111, soit vous pouvez cliquer avec le bouton droit sur l'élément dans la visionneuse HTML et cliquer sur "Journaliser les événements" afin de voir quels événements se déclenchent pour un élément DOM particulier. Je suppose que l'on pourrait le faire pour voir quels événements pourraient déclencher des fonctions particulières.

Dan Lew
la source
2

Avec la version 2.0, Firebug a introduit un panneau Événements , qui répertorie tous les événements de l'élément actuellement sélectionné dans le panneau HTML .

* Événements * panneau latéral dans Firebug

Il peut également afficher des écouteurs d'événements enveloppés dans des liaisons d'événements jQuery au cas où l'option Afficher les écouteurs enveloppés est cochée, que vous pouvez atteindre via le menu d'options du panneau Événements .

Avec ce panneau, le flux de travail pour déboguer un gestionnaire d'événements est le suivant:

  1. Sélectionnez l'élément avec l'écouteur d'événement que vous souhaitez déboguer
  2. Dans le panneau latéral Événements , cliquez avec le bouton droit sur la fonction sous l'événement associé et choisissez Définir le point d'arrêt
  3. Déclencher l'événement

=> L'exécution du script s'arrêtera à la première ligne de la fonction de gestionnaire d'événements et vous pouvez le déboguer par étapes.

Sebastian Zartner
la source
0

Firebug 2 intègre désormais le débogage / inspection des événements DOM.

MRalwasser
la source