J'ai besoin de trouver quels gestionnaires d'événements sont enregistrés sur un objet.
Par exemple:
$("#el").click(function() {...});
$("#el").mouseover(function() {...});
$("#el")
a clic et survolé enregistré.
Existe-t-il une fonction permettant de découvrir cela, et éventuellement de parcourir les gestionnaires d'événements?
Si ce n'est pas possible sur un objet jQuery avec des méthodes appropriées, est-ce possible sur un objet DOM simple?
Depuis jQuery 1.8, les données d'événement ne sont plus disponibles à partir de "l'API publique" pour les données. Lire cet article de blog jQuery . Vous devriez maintenant utiliser ceci à la place:
jQuery._data( elem, "events" );
elem
devrait être un élément HTML, pas un objet jQuery, ni un sélecteur.
Veuillez noter qu'il s'agit d'une structure interne "privée" et qu'elle ne devrait pas être modifiée. Utilisez-le uniquement à des fins de débogage.
Dans les anciennes versions de jQuery, vous devrez peut-être utiliser l'ancienne méthode, à savoir:
jQuery( elem ).data( "events" );
Vous pouvez le faire en explorant les événements (à partir de jQuery 1.8+), comme ceci:
$.each($._data($("#id")[0], "events"), function(i, event) {
// i is the event type, like "click"
$.each(event, function(j, h) {
// h.handler is the function being called
});
});
Voici un exemple avec lequel vous pouvez jouer:
$(function() {
$("#el").click(function(){ alert("click"); });
$("#el").mouseover(function(){ alert("mouseover"); });
$.each($._data($("#el")[0], "events"), function(i, event) {
output(i);
$.each(event, function(j, h) {
output("- " + h.handler);
});
});
});
function output(text) {
$("#output").html(function(i, h) {
return h + text + "<br />";
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="el">Test</div>
<code>
<span id="output"></span>
</code>
Pour jQuery 1.8+, cela ne fonctionnera plus car les données internes sont placées dans un objet différent.
La dernière méthode non officielle (mais fonctionne également dans les versions précédentes, du moins dans la version 1.7.2) est la suivante: - $._data(element, "events")
Le trait de soulignement ("_") est ce qui fait la différence ici. En interne, il appelle $.data(element, name, null, true)
, le dernier (quatrième) paramètre est interne ("pvt").
Prise sans vergogne, mais vous pouvez utiliser findHandlerJS
Pour l'utiliser, vous devez simplement inclure findHandlersJS (ou simplement copier-coller le code JavaScript brut dans la fenêtre de la console de chrome) et spécifier le type d'événement et un sélecteur jQuery pour les éléments que vous êtes. intéressé par.
Pour votre exemple, vous pouvez rapidement trouver les gestionnaires d’événements que vous avez mentionnés en faisant
findEventHandlers("click", "#el")
findEventHandlers("mouseover", "#el")
C'est ce qui est retourné:
Vous pouvez l'essayer ici
J'utilise eventbug plugin pour firebug à cette fin.
J'ai combiné les deux solutions de @jps à une seule fonction:
jQuery.fn.getEvents = function() {
if (typeof(jQuery._data) == 'function') {
return jQuery._data(this.get(0), 'events') || {};
} else if (typeof(this.data) == 'function') { // jQuery version < 1.7.?
return this.data('events') || {};
}
return {};
};
Mais attention, cette fonction ne peut renvoyer que les événements définis à l'aide de jQuery.
À partir de la version 1.9, il n'existe aucun moyen documenté de récupérer les événements, mis à part l'utilisation du plug-in Migrate pour restaurer l'ancien comportement. Vous pouvez utiliser la méthode _.data () comme le mentionne jps, mais il s'agit d'une méthode interne. Faites donc ce qui vous convient et utilisez le plug-in Migrate si vous avez besoin de cette fonctionnalité.
De la documentation de jQuery sur .data("events")
Avant 1.9, .data ("events") pouvait être utilisé pour récupérer la structure de données d'événement interne non documentée de jQuery pour un élément si aucun autre code n'avait défini un élément de données portant le nom "events". Ce cas particulier a été supprimé en 1.9. Il n'y a pas d'interface publique pour récupérer cette structure de données interne et celle-ci reste non documentée. Cependant, le plug-in jQuery Migrate restaure ce comportement pour le code qui en dépend.
J'ai créé un sélecteur jQuery personnalisé qui vérifie à la fois le cache des gestionnaires d'événements affectés de jQuery et les éléments qui utilisent la méthode native pour les ajouter:
(function($){
$.find.selectors[":"].event = function(el, pos, match) {
var search = (function(str){
if (str.substring(0,2) === "on") {str = str.substring(2);}
return str;
})(String(match[3]).trim().toLowerCase());
if (search) {
var events = $._data(el, "events");
return ((events && events.hasOwnProperty(search)) || el["on"+search]);
}
return false;
};
})(jQuery);
Exemple:
$(":event(click)")
Cela retournera les éléments ayant un gestionnaire de clic attaché.
Dans un navigateur moderne avec ECMAScript 5.1/Array.prototype.map
, vous pouvez également utiliser
jQuery._data(DOCUMENTELEMENT,'events')["EVENT_NAME"].map(function(elem){return elem.handler;});
dans la console de votre navigateur, qui imprimera la source des gestionnaires, séparés par des virgules. Utile pour jeter un coup d'œil sur tout ce qui se passe sur un événement particulier.
Pour rechercher des événements sur un élément:
var events = $._data(element, "events")
Notez que cela ne fonctionnera qu'avec les gestionnaires d’événements directs, si vous utilisez $ (document) .on ("nom-événement", "sélecteur jq", fonction () {// logique}), vous voudrez voir le getEvents fonctionne au bas de cette réponse
Par exemple:
var events = $._data(document.getElementById("myElemId"), "events")
ou
var events = $._data($("#myElemId")[0], "events")
Exemple complet:
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
<script>
$(function() {
$("#textDiv").click(function() {
//Event Handling
});
var events = $._data(document.getElementById('textDiv'), "events");
var hasEvents = (events != null);
});
</script>
</head>
<body>
<div id="textDiv">Text</div>
</body>
</html>
n moyen plus complet de vérifier, incluant les écouteurs dynamiques, installé avec $ (document) .on
function getEvents(element) {
var elemEvents = $._data(element, "events");
var allDocEvnts = $._data(document, "events");
for(var evntType in allDocEvnts) {
if(allDocEvnts.hasOwnProperty(evntType)) {
var evts = allDocEvnts[evntType];
for(var i = 0; i < evts.length; i++) {
if($(element).is(evts[i].selector)) {
if(elemEvents == null) {
elemEvents = {};
}
if(!elemEvents.hasOwnProperty(evntType)) {
elemEvents[evntType] = [];
}
elemEvents[evntType].Push(evts[i]);
}
}
}
}
return elemEvents;
}
Exemple d'utilisation:
getEvents($('#myElemId')[0])
Je dois dire que beaucoup de réponses sont intéressantes, mais récemment, j'ai eu un problème similaire et la solution était extrêmement simple en allant dans le sens du DOM. C'est différent parce que vous ne faites pas une itération mais que vous visez directement l'événement dont vous avez besoin, mais je donnerai ci-dessous une réponse plus générale.
J'ai eu une image dans une rangée:
<table>
<td><tr><img class="folder" /></tr><tr>...</tr></td>
</table>
Et cette image était associée à un gestionnaire d'événements de clic:
imageNode.click(function () { ... });
Mon intention était d’étendre la zone cliquable à l’ensemble de la ligne; j’ai donc d’abord obtenu toutes les images et les lignes relatives:
tableNode.find("img.folder").each(function () {
var tr;
tr = $(this).closest("tr");
// <-- actual answer
});
Maintenant, dans la ligne réponse réelle je viens de faire comme suit, en donnant une réponse à la question initiale:
tr.click(this.onclick);
J'ai donc récupéré le gestionnaire d'événements directement à partir de l'élément DOM et l'ai placé dans le gestionnaire d'événements de clic jQuery. Fonctionne comme un charme.
Passons maintenant au cas général. Dans les vieux jours d'avant le jQuery, vous pouviez obtenir tous les événements attachés à un objet avec deux fonctions simples mais puissantes offertes aux mortels par Douglas Crockford:
function walkTheDOM(node, func)
{
func(node);
node = node.firstChild;
while (node)
{
walkTheDOM(node, func);
node = node.nextSibling;
}
}
function purgeEventHandlers(node)
{
walkTheDOM(node, function (n) {
var f;
for (f in n)
{
if (typeof n[f] === "function")
{
n[f] = null;
}
}
});
}
Essayez le plug-in jquery debugger si vous utilisez chrome: https://chrome.google.com/webstore/detail/jquery-debugger/dbhhnnnpaeobfddmlalhnehgclcmjimi?hl=fr
Les événements peuvent être récupérés en utilisant:
jQuery(elem).data('events');
ou jQuery 1.8+:
jQuery._data(elem, 'events');
Remarque: Les événements liés à l'aide de $('selector').live('event', handler)
peuvent être extraits à l'aide de:
jQuery(document).data('events')
Une autre façon de le faire est d’utiliser simplement jQuery pour récupérer l’élément, puis de passer par le Javascript pour obtenir et définir et jouer avec les gestionnaires d’événements. Par exemple:
var oldEventHandler = $('#element')[0].onclick;
// Remove event handler
$('#element')[0].onclick = null;
// Switch it back
$('#element')[0].onclick = oldEventHandler;