Comment consignez-vous tous les événements déclenchés par un élément dans jQuery?

95

Je voudrais voir tous les événements déclenchés par un champ d'entrée lorsqu'un utilisateur interagit avec lui. Cela comprend des choses comme:

  1. En cliquant dessus.
  2. En cliquant dessus.
  3. Tabbing dedans.
  4. Tabbing loin de lui.
  5. Ctrl+ Cet Ctrl+ Vsur le clavier.
  6. Faites un clic droit -> Coller.
  7. Faites un clic droit -> Couper.
  8. Faites un clic droit -> Copier.
  9. Glisser-déposer du texte depuis une autre application.
  10. Le modifier avec Javascript.
  11. Le modifier avec un outil de débogage, comme Firebug.

Je voudrais l'afficher en utilisant console.log. Est-ce possible dans Javascript / jQuery, et si oui, comment puis-je le faire?

Daniel T.
la source
Votre question telle quelle est intéressante, mais vous avez dit dans un commentaire que "Ce que je recherchais était plutôt une liste de tous les événements en cours de licenciement, donc je sais lesquels sont disponibles pour que je puisse m'accrocher" - pourquoi n'avez-vous pas simplement demander ça? Le doco de MSDN est assez bon pour cela: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - tous les événements répertoriés ne sont pas pris en charge dans tous les navigateurs, mais si vous vérifiez le doco pour event 'on_xyz_' il vous dira "Cet événement est défini en HTML 4.0.", ou "Il n'y a pas de norme publique qui s'applique à cet événement", ou autre.
nnnnnn
2
La réponse - stackoverflow.com/questions/7439570/…
neaumusic

Réponses:

65
$(element).on("click mousedown mouseup focus blur keydown change",function(e){
     console.log(e);
});

Cela vous donnera beaucoup (mais pas toutes) d'informations sur le déclenchement d'un événement ... à part le coder manuellement comme ça, je ne peux penser à aucun autre moyen de le faire.

Joseph Marikle
la source
Bizarre comme Shawn et toi avez mal orthographié function, et de la même manière :).
Daniel T.
1
Il semble que cette méthode liera tous les événements natifs. Je suppose qu'il n'y a aucun moyen d'afficher des événements personnalisés, par exemple si un plugin déclenche des événements personnalisés?
Daniel T.
2
J'accepte ceci comme réponse, mais la vraie réponse à ma question est "oui et non". Ce que je cherchais, c'était plutôt une liste de tous les événements en cours de déclenchement afin que je sache lesquels sont disponibles pour moi. Dans ce cas, je peux voir quand les événements sont déclenchés, mais je dois en connaître le nom au préalable.
Daniel T.
3
@Joseph: à propos de votre commentaire précédent "le focus n'est pas un événement natif" - euh ... oui ça l'est, un qui existe depuis bien avant jQuery (et avant Chrome et FF, d'ailleurs). Vous pouvez également ajouter blurà votre liste d'événements.
nnnnnn
3
monitorEvents (document) est la vraie réponse
neaumusic
206

Je ne sais pas pourquoi personne n'utilise ça ... (peut-être parce que ce n'est qu'un truc web)

Ouvrez la console:

monitorEvents(document.body); // logs all events on the body

monitorEvents(document.body, 'mouse'); // logs mouse events on the body

monitorEvents(document.body.querySelectorAll('input')); // logs all events on inputs
Sidonaldson
la source
7
Cela ne couvre pas les événements personnalisés, mais cela aide vraiment à comprendre la pile d'événements.
sidonaldson
C'est la bonne réponse. Vous ne voulez pas utiliser console.log dans le code de production, c'est bien d'utiliser la console pour les événements de débogage
neaumusic
1
Googleing monitorEventsne donne aucune information pertinente à ce sujet, aussi, je soupçonne fortement que c'est très non standard
vsync
3
@vsync essayez "monitorEvents" entre guillemets. Cela fait partie de l'objet console mais dépend du navigateur. Ce n'est qu'un outil de débogage car cela dépend de la console ... donc être standard n'est pas pertinent
Sidonaldson
2
Notez que vous pouvez également utiliser quelque chose comme monitorEvents($0, 'mouse');pour enregistrer tous les événements d'un élément inspecté (clic droit> «Inspecter»). ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo
32

Il existe une belle manière générique d'utiliser la collection .data ('events'):

function getEventsList($obj) {
    var ev = new Array(),
        events = $obj.data('events'),
        i;
    for(i in events) { ev.push(i); }
    return ev.join(' ');
}

$obj.on(getEventsList($obj), function(e) {
    console.log(e);
});

Cela enregistre chaque événement qui a déjà été lié à l'élément par jQuery au moment où cet événement spécifique est déclenché. Ce code m'a été très utile à plusieurs reprises.

Btw: Si vous voulez voir tous les événements possibles être déclenchés sur un objet, utilisez firebug: faites un clic droit sur l'élément DOM dans l'onglet html et cochez "Log Events". Chaque événement est ensuite enregistré sur la console (c'est parfois un peu ennuyeux car il enregistre chaque mouvement de la souris ...).

Simon
la source
19
$('body').on("click mousedown mouseup focus blur keydown change mouseup click dblclick mousemove mouseover mouseout mousewheel keydown keyup keypress textInput touchstart touchmove touchend touchcancel resize scroll zoom focus blur select change submit reset",function(e){
     console.log(e);
}); 
maudulus
la source
3
Réponse la plus complète
leymannx
12

Je sais que la réponse a déjà été acceptée, mais je pense qu'il pourrait y avoir un moyen un peu plus fiable où vous ne devez pas nécessairement connaître le nom de l'événement à l'avance. Cela ne fonctionne que pour les événements natifs pour autant que je sache, pas pour ceux personnalisés qui ont été créés par des plugins. J'ai choisi d'omettre l'utilisation de jQuery pour simplifier un peu les choses.

let input = document.getElementById('inputId');

Object.getOwnPropertyNames(input)
  .filter(key => key.slice(0, 2) === 'on')
  .map(key => key.slice(2))
  .forEach(eventName => {
    input.addEventListener(eventName, event => {
      console.log(event.type);
      console.log(event);
    });
  });

J'espère que cela aidera quiconque lit ceci.

ÉDITER

J'ai donc vu une autre question ici qui était similaire, donc une autre suggestion serait de faire ce qui suit:

monitorEvents(document.getElementById('inputId'));
Patrick Roberts
la source
C'est la solution la plus élégante du groupe. Je suppose qu'il serait impossible de découvrir des événements personnalisés car ceux-ci pourraient être émis via dispatchEvent (). Pourtant, cela couvre tout le reste dans un morceau de code compact et sans dépendance.
Roberto
10

Vieux fil, je sais. J'avais aussi besoin de quelque chose pour surveiller les événements et j'ai écrit cette (excellente) solution très pratique. Vous pouvez surveiller tous les événements avec ce hook (dans la programmation Windows, cela s'appelle un hook). Ce hook n'affecte pas le fonctionnement de votre logiciel / programme.

Dans le journal de la console, vous pouvez voir quelque chose comme ceci:

journal de la console

Explication de ce que vous voyez:

Dans le journal de la console, vous verrez tous les événements que vous sélectionnez (voir ci-dessous "comment utiliser" ) et affichez le type d'objet, le (s) nom (s) de classe, l'ID, <: nom de la fonction>, <: eventname>. La mise en forme des objets est de type CSS.

Lorsque vous cliquez sur un bouton ou sur tout événement lié, vous le verrez dans le journal de la console.

Le code que j'ai écrit:

function setJQueryEventHandlersDebugHooks(bMonTrigger, bMonOn, bMonOff)
{
   jQuery.fn.___getHookName___ = function()    
       {
          // First, get object name
         var sName = new String( this[0].constructor ),
         i = sName.indexOf(' ');
         sName = sName.substr( i, sName.indexOf('(')-i );    

         // Classname can be more than one, add class points to all
         if( typeof this[0].className === 'string' )
         {
           var sClasses = this[0].className.split(' ');
           sClasses[0]='.'+sClasses[0];
           sClasses = sClasses.join('.');
           sName+=sClasses;
         }
         // Get id if there is one
         sName+=(this[0].id)?('#'+this[0].id):'';
         return sName;
       };

   var bTrigger        = (typeof bMonTrigger !== "undefined")?bMonTrigger:true,
       bOn             = (typeof bMonOn !== "undefined")?bMonOn:true,
       bOff            = (typeof bMonOff !== "undefined")?bMonOff:true,
       fTriggerInherited = jQuery.fn.trigger,
       fOnInherited    = jQuery.fn.on,
       fOffInherited   = jQuery.fn.off;

   if( bTrigger )
   {
    jQuery.fn.trigger = function()
    {
     console.log( this.___getHookName___()+':trigger('+arguments[0]+')' );
     return fTriggerInherited.apply(this,arguments);
    };
   }

   if( bOn )
   {
    jQuery.fn.on = function()
    {
     if( !this[0].__hooked__ ) 
     {
       this[0].__hooked__ = true; // avoids infinite loop!
       console.log( this.___getHookName___()+':on('+arguments[0]+') - binded' );
       $(this).on( arguments[0], function(e)
       {
         console.log( $(this).___getHookName___()+':'+e.type );
       });
     }
     var uResult = fOnInherited.apply(this,arguments);
     this[0].__hooked__ = false; // reset for another event
     return uResult;
    };
   }

   if( bOff )
   {
    jQuery.fn.off = function()
    {
     if( !this[0].__unhooked__ ) 
     {
       this[0].__unhooked__ = true; // avoids infinite loop!
       console.log( this.___getHookName___()+':off('+arguments[0]+') - unbinded' );
       $(this).off( arguments[0] );
     }

     var uResult = fOffInherited.apply(this,arguments);
     this[0].__unhooked__ = false; // reset for another event
     return uResult;
    };
   }
}

Exemples comment l'utiliser:

Surveillez tous les événements:

setJQueryEventHandlersDebugHooks();

Surveiller uniquement tous les déclencheurs:

setJQueryEventHandlersDebugHooks(true,false,false);

Surveiller uniquement tous les événements ON:

setJQueryEventHandlersDebugHooks(false,true,false);

Surveiller tous les dissociations OFF uniquement:

setJQueryEventHandlersDebugHooks(false,false,true);

Remarques / avis:

  • Utilisez-le uniquement pour le débogage, désactivez-le lors de l'utilisation dans la version finale du produit
  • Si vous voulez voir tous les événements, vous devez appeler cette fonction directement après le chargement de jQuery
  • Si vous souhaitez voir seulement moins d'événements, vous pouvez appeler la fonction au moment où vous en avez besoin
  • Si vous voulez l'exécuter automatiquement, placez () (); autour de la fonction

J'espère que ça aide! ;-)

Codebeat
la source
Salut @AmirFo, merci d'avoir essayé. Comme vous ne fournissez aucun exemple de ce que vous avez fait, il n'est pas possible de voir si le problème est dans votre code ou le mien. Comme il y en a d'autres qui ont utilisé cet exemple avec succès, il est possible que vous ayez fait une erreur. Avez-vous vérifié votre code pour les erreurs?
Codebeat
Il n'y a eu aucune erreur. J'ai déclenché certains événements, mais aucun journal n'est apparu dans la console! J'utilise la dernière version de chrome dans ubuntu, linux.
Amir Fo le
@AmirFo: L'avez-vous essayé aussi dans Firefox? Quelle version de jQuery?
Codebeat le
@AmirFo: Comment avez-vous déclenché les événements? Avez-vous lié des événements aux éléments DOM avant de les déclencher?
Codebeat le
4

https://github.com/robertleeplummerjr/wiretap.js

new Wiretap({
  add: function() {
      //fire when an event is bound to element
  },
  before: function() {
      //fire just before an event executes, arguments are automatic
  },
  after: function() {
      //fire just after an event executes, arguments are automatic
  }
});
Robert Plummer
la source
1
Pouvez-vous donner plus d'informations sur la façon dont cela fonctionne et ce qu'il fait exactement? Comment puis-je l'attacher à un élément?
Josiah
Ce script modifie HTMLElement.prototype.addEventListeneret ne devrait probablement pas être utilisé en production, mais il m'a déjà été d'une grande aide à des fins de débogage.
Günter Zöchbauer
1
Cela ne fonctionne pas avec 1 élément, cela fonctionne pour TOUS. Il puise dans le gestionnaire d'événements de la fenêtre et écoute tout ce qui se passe. Il fonctionne avec les gestionnaires d'événements natifs et jQuery.
Robert Plummer
2

Ajoutez simplement ceci à la page et pas d'autres soucis, gérera le repos pour vous:

$('input').live('click mousedown mouseup focus keydown change blur', function(e) {
     console.log(e);
});

Vous pouvez également utiliser console.log ('Input event:' + e.type) pour vous faciliter la tâche.

Shawn Khameneh
la source
3
C'est étrange comment toi et Joseph avez mal orthographié function, et de la même manière :).
Daniel T.
lol, hé ... il en avait écrit et j'avais une amélioration. ;)
Shawn Khameneh
1
Ne me laissez pas commenter l'autre réponse, vous pouvez utiliser .data ("événements") pour saisir la liste des événements.
Shawn Khameneh
Comment ça marche? J'ai essayé $('input').data('events')et ça retourne indéfini.
Daniel T.
Cela renverra les événements liés actuels, qui incluent les événements personnalisés. Si aucun événement n'est lié, il renverra undefined.
Shawn Khameneh
1

ÉTAPE 1: Recherchez eventsun HTML elementsur le developer console:

entrez la description de l'image ici

ÉTAPE 2: Écoutez ce que eventsnous voulons capturer:

$(document).on('ch-ui-container-closed ch-ui-container-opened', function(evt){
 console.log(evt);
});

Bonne chance...

Akash
la source
1

J'ai récemment trouvé et modifié cet extrait d'un article SO existant que je n'ai pas pu retrouver mais je l'ai trouvé très utile

// specify any elements you've attached listeners to here
const nodes = [document]

// https://developer.mozilla.org/en-US/docs/Web/Events
const logBrowserEvents = () => {
  const AllEvents = {
    AnimationEvent: ['animationend', 'animationiteration', 'animationstart'],
    AudioProcessingEvent: ['audioprocess'],
    BeforeUnloadEvent: ['beforeunload'],
    CompositionEvent: [
      'compositionend',
      'compositionstart',
      'compositionupdate',
    ],
    ClipboardEvent: ['copy', 'cut', 'paste'],
    DeviceLightEvent: ['devicelight'],
    DeviceMotionEvent: ['devicemotion'],
    DeviceOrientationEvent: ['deviceorientation'],
    DeviceProximityEvent: ['deviceproximity'],
    DragEvent: [
      'drag',
      'dragend',
      'dragenter',
      'dragleave',
      'dragover',
      'dragstart',
      'drop',
    ],
    Event: [
      'DOMContentLoaded',
      'abort',
      'afterprint',
      'beforeprint',
      'cached',
      'canplay',
      'canplaythrough',
      'change',
      'chargingchange',
      'chargingtimechange',
      'checking',
      'close',
      'dischargingtimechange',
      'downloading',
      'durationchange',
      'emptied',
      'ended',
      'error',
      'fullscreenchange',
      'fullscreenerror',
      'input',
      'invalid',
      'languagechange',
      'levelchange',
      'loadeddata',
      'loadedmetadata',
      'noupdate',
      'obsolete',
      'offline',
      'online',
      'open',
      'open',
      'orientationchange',
      'pause',
      'play',
      'playing',
      'pointerlockchange',
      'pointerlockerror',
      'ratechange',
      'readystatechange',
      'reset',
      'seeked',
      'seeking',
      'stalled',
      'submit',
      'success',
      'suspend',
      'timeupdate',
      'updateready',
      'visibilitychange',
      'volumechange',
      'waiting',
    ],
    FocusEvent: [
      'DOMFocusIn',
      'DOMFocusOut',
      'Unimplemented',
      'blur',
      'focus',
      'focusin',
      'focusout',
    ],
    GamepadEvent: ['gamepadconnected', 'gamepaddisconnected'],
    HashChangeEvent: ['hashchange'],
    KeyboardEvent: ['keydown', 'keypress', 'keyup'],
    MessageEvent: ['message'],
    MouseEvent: [
      'click',
      'contextmenu',
      'dblclick',
      'mousedown',
      'mouseenter',
      'mouseleave',
      'mousemove',
      'mouseout',
      'mouseover',
      'mouseup',
      'show',
    ],
    // https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Mutation_events
    MutationNameEvent: ['DOMAttributeNameChanged', 'DOMElementNameChanged'],
    MutationEvent: [
      'DOMAttrModified',
      'DOMCharacterDataModified',
      'DOMNodeInserted',
      'DOMNodeInsertedIntoDocument',
      'DOMNodeRemoved',
      'DOMNodeRemovedFromDocument',
      'DOMSubtreeModified',
    ],
    OfflineAudioCompletionEvent: ['complete'],
    OtherEvent: ['blocked', 'complete', 'upgradeneeded', 'versionchange'],
    UIEvent: [
      'DOMActivate',
      'abort',
      'error',
      'load',
      'resize',
      'scroll',
      'select',
      'unload',
    ],
    PageTransitionEvent: ['pagehide', 'pageshow'],
    PopStateEvent: ['popstate'],
    ProgressEvent: [
      'abort',
      'error',
      'load',
      'loadend',
      'loadstart',
      'progress',
    ],
    SensorEvent: ['compassneedscalibration', 'Unimplemented', 'userproximity'],
    StorageEvent: ['storage'],
    SVGEvent: [
      'SVGAbort',
      'SVGError',
      'SVGLoad',
      'SVGResize',
      'SVGScroll',
      'SVGUnload',
    ],
    SVGZoomEvent: ['SVGZoom'],
    TimeEvent: ['beginEvent', 'endEvent', 'repeatEvent'],
    TouchEvent: [
      'touchcancel',
      'touchend',
      'touchenter',
      'touchleave',
      'touchmove',
      'touchstart',
    ],
    TransitionEvent: ['transitionend'],
    WheelEvent: ['wheel'],
  }

  const RecentlyLoggedDOMEventTypes = {}

  Object.keys(AllEvents).forEach((DOMEvent) => {
    const DOMEventTypes = AllEvents[DOMEvent]

    if (Object.prototype.hasOwnProperty.call(AllEvents, DOMEvent)) {
      DOMEventTypes.forEach((DOMEventType) => {
        const DOMEventCategory = `${DOMEvent} ${DOMEventType}`

        nodes.forEach((node) => {
          node.addEventListener(
            DOMEventType,
            (e) => {
              if (RecentlyLoggedDOMEventTypes[DOMEventCategory]) return

              RecentlyLoggedDOMEventTypes[DOMEventCategory] = true

              // NOTE: throttle continuous events
              setTimeout(() => {
                RecentlyLoggedDOMEventTypes[DOMEventCategory] = false
              }, 1000)

              const isActive = e.target === document.activeElement

              // https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/activeElement
              const hasActiveElement = document.activeElement !== document.body

              const msg = [
                DOMEventCategory,
                'target:',
                e.target,
                ...(hasActiveElement
                  ? ['active:', document.activeElement]
                  : []),
              ]

              if (isActive) {
                console.info(...msg)
              }
            },
            true,
          )
        })
      })
    }
  })
}
logBrowserEvents()
// export default logBrowserEvents
lfender6445
la source
1
function bindAllEvents (el) {
  for (const key in el) {
      if (key.slice(0, 2) === 'on') {
          el.addEventListener(key.slice(2), e => console.log(e.type));
      }
  }
}
bindAllEvents($('.yourElement'))

Cela utilise un peu d'ES6 pour la beauté, mais peut également être facilement traduit pour les anciens navigateurs. Dans la fonction associée aux écouteurs d'événements, il s'agit actuellement de déconnecter simplement le type d'événement qui s'est produit, mais c'est ici que vous pouvez imprimer des informations supplémentaires, ou en utilisant un boîtier de commutation sur le e.type, vous ne pouvez imprimer des informations que sur des événements spécifiques

Lisa
la source
0

Voici un moyen non jquery de surveiller les événements dans la console avec votre code et sans utiliser monitorEvents () car cela ne fonctionne que dans Chrome Developer Console. Vous pouvez également choisir de ne pas surveiller certains événements en modifiant le tableau no_watch.

    function getEvents(obj) {
    window["events_list"] = [];
    var no_watch = ['mouse', 'pointer']; // Array of event types not to watch
    var no_watch_reg = new RegExp(no_watch.join("|"));

    for (var prop in obj) {
        if (prop.indexOf("on") === 0) {
            prop = prop.substring(2); // remove "on" from beginning
            if (!prop.match(no_watch_reg)) {
                window["events_list"].push(prop);
                window.addEventListener(prop, function() {
                    console.log(this.event); // Display fired event in console
                } , false);
            }
        }
    }
    window["events_list"].sort(); // Alphabetical order 

}

getEvents(document); // Put window, document or any html element here
console.log(events_list); // List every event on element
Jeff Baker
la source