web-dev-qa-db-fra.com

jQuery recherche les gestionnaires d'événements enregistrés avec un objet

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?

528
ages04

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" );
660
jps

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>
79
Nick Craver

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").

35
PhistucK

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é:

  • élément
    L'élément réel dans lequel le gestionnaire d'événements a été enregistré dans
  • événements
    Tableau contenant des informations sur les gestionnaires d’événements jquery pour le type d’événement qui nous intéresse (par exemple, clic, modification, etc.)
    • gestionnaire
      Méthode de gestionnaire d’événements que vous pouvez voir en cliquant dessus avec le bouton droit de la souris et en sélectionnant Afficher la définition de la fonction
    • sélecteur
      Le sélecteur prévoyait des événements délégués. Ce sera vide pour les événements directs.
    • des cibles
      Répertorie les éléments que ce gestionnaire d'événements cible. Par exemple, pour un gestionnaire d'événements délégué enregistré dans l'objet de document et qui cible tous les boutons d'une page, cette propriété répertorie tous les boutons de la page. Vous pouvez les survoler et les voir surlignés en chrome.

Vous pouvez l'essayer ici

32
Rui

J'utilise eventbug plugin pour firebug à cette fin.

12
Anton

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.

9
algorhythm

À 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.

5
oligofren

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é.

3
Erutan409

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.

2
Jesan Fafon

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])
2
Tom G

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;
      }
    }
  });
}
1
pid
1
Marquinho Peli

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')
1
R. Oosterholt

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;
0
tempranova