J'ai une page où certains auditeurs d'événements sont attachés aux boîtes de saisie et aux boîtes de sélection. Existe-t-il un moyen de savoir quel événement les auditeurs observent un noeud DOM particulier et pour quel événement?
Les événements sont joints en utilisant:
Event.observe
; addEventListener
; Si vous avez juste besoin d'inspecter ce qui se passe sur une page, vous pouvez essayer le bookmarklet Visual Event .
Mise à jour : Visual Event 2 disponible;
Cela dépend de la façon dont les événements sont joints. Pour présumer l'illustration, nous avons le gestionnaire de clic suivant:
var handler = function() { alert('clicked!') };
Nous allons l'attacher à notre élément en utilisant différentes méthodes, certaines qui permettent l'inspection et celles qui n'en ont pas.
Méthode A) gestionnaire d'événement unique
element.onclick = handler; // inspect alert(element.onclick); // alerts "function() { alert('clicked!') }"
Méthode B) gestionnaires d'événements multiples
if(element.addEventListener) { // DOM standard element.addEventListener('click', handler, false) } else if(element.attachEvent) { // IE element.attachEvent('onclick', handler) } // cannot inspect element to find handlers
Méthode C): jQuery
$(element).click(handler);
1.3.x
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, value) { alert(value) // alerts "function() { alert('clicked!') }" })
1.4.x (stocke le gestionnaire dans un objet)
// inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { alert(handlerObj.handler) // alerts "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace })
(Voir jQuery.fn.data
et jQuery.data
)
Méthode D): Prototype (désordonné)
$(element).observe('click', handler);
1.5.x
// inspect Event.observers.each(function(item) { if(item[0] == element) { alert(item[2]) // alerts "function() { alert('clicked!') }" } })
1.6 à 1.6.0.3, inclusivement (a été très difficile ici)
// inspect. "_eventId" is for < 1.6.0.3 while // "_prototypeEventID" was introduced in 1.6.0.3 var clickEvents = Event.cache[element._eventId || (element._prototypeEventID || [])[0]].click; clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" })
1.6.1 (peu mieux)
// inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" })
Chrome, Firefox, Vivaldi et Safari supportent getEventListeners(domElement)
dans leur console d'outils de développement.
Pour la plupart des fins de débogage, cela pourrait être utilisé.
Vous trouverez ci-dessous une très bonne référence pour l'utiliser: https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject
WebKit Inspector dans les navigateurs Chrome ou Safari fait maintenant cela. Il affichera les auditeurs d'événements pour un élément DOM lorsque vous le sélectionnez dans le volet Éléments.
Il est possible d'énumérer tous les auditeurs d'événements en JavaScript: ce n'est pas si difficile; Il suffit de pirater la méthode du prototype
des éléments HTML ( avant d' ajouter les auditeurs).
function reportIn(e){ var a = this.lastListenerInfo[this.lastListenerInfo.length-1]; console.log(a) } HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener; HTMLAnchorElement.prototype.addEventListener = function(a,b,c){ this.realAddEventListener(a,reportIn,c); this.realAddEventListener(a,b,c); if(!this.lastListenerInfo){ this.lastListenerInfo = new Array()}; this.lastListenerInfo.push({a : a, b : b , c : c}); };
Maintenant, chaque élément d'ancrage ( a
) aura une propriété lastListenerInfo
qui contient tous ses auditeurs. Et cela fonctionne même pour éliminer les auditeurs avec des fonctions anonymes.
(Réécriture de la réponse de cette question puisqu'il est pertinent ici.)
Lors du débogage, si vous voulez juste voir les événements, je vous recommande …
Si vous souhaitez utiliser les événements dans votre code et que vous utilisez jQuery avant la version 1.8 , vous pouvez utiliser:
$(selector).data("events")
Pour obtenir les événements. À partir de la version 1.8, l'utilisation de .data ("événements") est interrompue (voir ce ticket de bogue ). Vous pouvez utiliser:
$._data(element, "events")
Un autre exemple: Écrivez tous les événements de clic sur un certain lien vers la console:
var $myLink = $('a.myClass'); console.log($._data($myLink[0], "events").click);
(Voir http://jsfiddle.net/HmsQC/ pour un exemple de travail)
Malheureusement, en utilisant des données $ ._, cela n'est pas recommandé, sauf pour le débogage car il s'agit d'une structure jQuery interne, et pourrait changer dans les versions ultérieures. Malheureusement, je ne connais aucun autre moyen facile d'accéder aux événements.
1: Prototype.observe
utilise Element.addEventListener (voir le code source )
2: Vous pouvez annuler Element.addEventListener
pour vous souvenir des auditeurs ajoutés (la propriété EventListenerList
été retirée de la proposition de spécification DOM3). Exécutez ce code avant qu'un événement ne soit joint:
(function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; this.eventListenerList[a].push(b); }; })();
Lisez tous les événements par:
var clicks = someElement.eventListenerList.click; if(clicks) clicks.forEach(function(f) { alert("I listen to this function: "+f.toString()); });
Et n'oubliez pas de remplacer Element.removeEventListener
pour supprimer l'événement de Element.eventListenerList
personnalisé.
3: la propriété Element.onclick
nécessite un soin particulier ici:
if(someElement.onclick) alert("I also listen tho this: "+someElement.onclick.toString());
4: n'oubliez pas l'attribut Element.onclick
contenu: il s'agit de deux choses différentes:
someElement.onclick = someHandler; // IDL attribute someElement.setAttribute("onclick","otherHandler(event)"); // content attribute
Donc, vous devez le gérer aussi:
var click = someElement.getAttribute("onclick"); if(click) alert("I even listen to this: "+click);
Le bookmarklet Visual Event (mentionné dans la réponse la plus populaire) ne vole que le cache du gestionnaire de bibliothèque personnalisé:
Il s'avère qu'il n'y a pas de méthode standard fournie par l'interface DOM recommandée par W3C pour savoir quels auditeurs d'événements sont attachés à un élément particulier. Bien que cela puisse sembler être un oubli, il y avait une proposition pour inclure une propriété appelée eventListenerList à la spécification DOM de niveau 3, mais a malheureusement été supprimée dans les versions ultérieures. En tant que tel, nous sommes forcés de regarder les bibliothèques Javascript individuelles, qui maintiennent généralement un cache d'événements attachés (afin qu'ils puissent ensuite être supprimés et effectuer d'autres abstractions utiles).
En tant que tel, pour que Visual Event affiche des événements, il doit pouvoir analyser les informations sur l'événement à partir d'une bibliothèque Javascript.
L'élimination des éléments peut être discutable (c'est-à-dire parce qu'il existe certaines fonctionnalités DOM spécifiques telles que les collections en direct, qui ne peuvent pas être codées dans JS), mais cela donne naissance à l'événementListenerList en mode natif et fonctionne dans Chrome, Firefox et Opera (ne fonctionne pas dans IE7 ).
Vous pouvez envelopper les méthodes DOM natives pour gérer les auditeurs d'événements en mettant ceci au sommet de votre <head>
:
<script> (function(w){ var originalAdd = w.addEventListener; w.addEventListener = function(){ // add your own stuff here to debug return originalAdd.apply(this, arguments); }; var originalRemove = w.removeEventListener; w.removeEventListener = function(){ // add your own stuff here to debug return originalRemove.apply(this, arguments); }; })(window); </script>
H / T @ les2
Utilisez getEventListeners dans Google Chrome:
getEventListeners(document.getElementByID('btnlogin')); getEventListeners($('#btnlogin'));
Si vous avez Firebug , vous pouvez utiliser console.dir(object or array)
pour imprimer un arbre agréable dans le journal de la console de n'importe quel scalaire, tableau ou objet JavaScript.
Essayer:
console.dir(clickEvents);
ou
console.dir(window);
Les outils de développement de Firefox le font maintenant. Les événements sont affichés en cliquant sur le bouton "ev" à droite de l'affichage de chaque élément, y compris les événements jQuery et DOM .
Opera 12 (pas le dernier moteur Chrome Webkit basé) Dragonfly a eu pendant un certain temps et est évidemment affiché dans la structure DOM. À mon avis, c'est un débogueur supérieur et c'est la seule raison de rester pourquoi j'utilise toujours la version Opera 12 (il n'y a pas de version v13, v14 et la fonctionnalité de v15 Webkit manque encore de Dragonfly)
Une solution entièrement fonctionnelle basée sur la réponse de Jan Turon – se comporte comme getEventListeners()
partir de la console:
(Il y a un petit bogue avec des doublons. Il ne cesse pas beaucoup de toute façon.)
(function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { if(c==undefined) c=false; this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; //this.removeEventListener(a,b,c); // TODO - handle duplicates.. this.eventListenerList[a].push({listener:b,useCapture:c}); }; Element.prototype.getEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined) return this.eventListenerList; return this.eventListenerList[a]; }; Element.prototype.clearEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined){ for(var x in (this.getEventListeners())) this.clearEventListeners(x); return; } var el = this.getEventListeners(a); if(el==undefined) return; for(var i = el.length - 1; i >= 0; --i) { var ev = el[i]; this.removeEventListener(a, ev.listener, ev.useCapture); } }; Element.prototype._removeEventListener = Element.prototype.removeEventListener; Element.prototype.removeEventListener = function(a,b,c) { if(c==undefined) c=false; this._removeEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; // Find the event in the list for(var i=0;i<this.eventListenerList[a].length;i++){ if(this.eventListenerList[a][i].listener==b, this.eventListenerList[a][i].useCapture==c){ // Hmm.. this.eventListenerList[a].splice(i, 1); break; } } if(this.eventListenerList[a].length==0) delete this.eventListenerList[a]; }; })();
Usage:
someElement.getEventListeners([name])
– liste de retour des auditeurs d'événements, si le nom est défini return array of listeners for that event
someElement.clearEventListeners([name])
– supprime tous les auditeurs de l'événement, si le nom est défini, supprime seulement les auditeurs de cet événement
Prototype 1.7.1
function get_element_registry(element) { var cache = Event.cache; if(element === window) return 0; if(typeof element._prototypeUID === 'undefined') { element._prototypeUID = Element.Storage.UID++; } var uid = element._prototypeUID; if(!cache[uid]) cache[uid] = {element: element}; return cache[uid]; }
J'essaie de le faire dans jQuery 2.1 et avec la méthode " $().click() -> $(element).data("events").click;
", cela ne fonctionne pas.
Je me suis rendu compte que seules les fonctions $ ._ data () fonctionnent dans mon cas:
$(document).ready(function(){ var node = $('body'); // Bind 3 events to body click node.click(function(e) { alert('hello'); }) .click(function(e) { alert('bye'); }) .click(fun_1); // Inspect the events of body var events = $._data(node[0], "events").click; var ev1 = events[0].handler // -> function(e) { alert('hello') var ev2 = events[1].handler // -> function(e) { alert('bye') var ev3 = events[2].handler // -> function fun_1() $('body') .append('<p> Event1 = ' + eval(ev1).toString() + '</p>') .append('<p> Event2 = ' + eval(ev2).toString() + '</p>') .append('<p> Event3 = ' + eval(ev3).toString() + '</p>'); }); function fun_1() { var txt = 'text del missatge'; alert(txt); }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> </body>
Il existe une jolie extension de jQuery Events :
( Source de sujet)