Question 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 Cliquez sur et mouseover inscrit.

Y a-t-il une fonction pour le savoir, et peut-être parcourir les gestionnaires d'événements?

Si ce n'est pas possible sur un objet jQuery par des méthodes correctes, est-ce possible sur un objet DOM simple?


495
2018-03-25 18:47


origine


Réponses:


A partir de jQuery 1.8, les données d'événement ne sont plus disponibles à partir de "l'API publique" pour les données. Lis ce blog de jQuery. Vous devriez maintenant l'utiliser à la place:

jQuery._data( elem, "events" );

elem devrait être un élément HTML, pas un objet jQuery ou un sélecteur.

Veuillez noter qu'il s'agit d'une structure interne «privée» et qu'elle ne doit pas être modifiée. Utilisez ceci à des fins de débogage uniquement.

Dans les anciennes versions de jQuery, vous pourriez avoir à utiliser l'ancienne méthode qui est:

jQuery( elem ).data( "events" );

617
2018-03-25 18:50



Vous pouvez le faire comme ceci:

$("#el").click(function(){ alert("click");});
$("#el").mouseover(function(){ alert("mouseover"); });

$.each($("#el").data("events"), function(i, e) {
    alert(i);
});
//alerts 'click' then 'mouseover'

Si vous utilisez jQuery 1.4+, cela alertera l'événement et les fonctions qui y sont liées:

$.each($("#el").data("events"), function(i, event) {
    alert(i);
    $.each(event, function(j, h) {
        alert(h.handler);
    });
});
//alerts: 
//'click'
//'function (){ alert("click"); }'
//'mouseover'
//'function(){ alert("mouseover"); }'

Vous pouvez jouer avec jsFiddle ici     Les


73
2018-03-25 20:21



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 qui fonctionne également dans les versions précédentes, au moins dans la version 1.7.2) est désormais: $._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").


36
2017-07-05 11:38



Bouchon sans vergogne, mais vous pouvez utiliser trouverHandlerJS

Pour l'utiliser, il vous suffit d'inclure findHandlersJS (ou simplement copier et coller le code javascript brut dans la fenêtre de la console de chrome) et spécifiez le type d'événement et un sélecteur de jquery pour les éléments qui vous intéressent.

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énement a été enregistré
  • é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 du gestionnaire d'événements réel 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 fourni pour les événements délégués. Il sera vide pour les événements directs.
    • cibles
      Liste avec les éléments ciblés par ce gestionnaire d'événements. Par exemple, pour un gestionnaire d'événements délégué qui est enregistré dans l'objet Document et cible tous les boutons d'une page, cette propriété répertorie tous les boutons de la page. Vous pouvez les planer et les voir surlignés en chrome.

Tu peux l'essayer ici


29
2018-01-21 15:05



j'utilise eventbug plugin à firebug à cet effet.


13
2017-07-26 06:10



J'ai combiné les deux solutions de @jps à une 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 retourner que les événements qui ont été définis avec jQuery lui-même.


8
2017-11-12 16:48



À partir de la version 1.9, il n'existe aucun moyen documenté de récupérer les événements, sauf pour utiliser le plug-in Migrate pour restaurer l'ancien comportement. Vous pouvez utiliser la méthode _.data () comme le mentionne jps, mais c'est une méthode interne. Alors, faites juste la bonne chose et utilisez le plugin 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 les fichiers jQuery   structure de données d'événement interne non documentée pour un élément si aucun autre   le code avait défini un élément de données avec le nom "events". Cette spéciale   l'affaire a été supprimée en 1.9. Il n'y a pas d'interface publique pour récupérer   cette structure de données interne, et il reste non documenté. cependant,   le plugin jQuery Migrate restaure ce comportement pour le code dépendant   sur lui.


6
2018-04-03 08:32



Dans un navigateur moderne avec ECMAScript 5.1 / Array.prototype.map, vous pouvez aussi 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, délimitée par des virgules. Utile pour jeter un coup d'œil à tout ce qui tourne sur un événement particulier.


3
2018-05-06 22:55



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 utilisant la méthode DOM. C'est différent parce que vous ne itérez pas mais que vous visez directement l'événement dont vous avez besoin, mais je vais donner une réponse plus générale.

J'avais 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 à la ligne entière, donc j'ai 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 le réponse réelle Je viens de faire la ligne suivante, en répondant à 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 click de jQuery. Fonctionne comme un charme.

Maintenant, au cas général. Dans les anciens jours d'avant JQuery, vous pouviez attacher tous les événements à un objet avec deux fonctions simples, mais puissantes, qui nous avaient été données par les mortels. 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;
      }
    }
  });
}

2
2017-10-14 14:44