Come si registrano tutti gli eventi attivati ​​da un elemento in jQuery?


94

Mi piacerebbe vedere tutti gli eventi attivati ​​da un campo di input mentre un utente interagisce con esso. Questo include cose come:

  1. Cliccandoci sopra.
  2. Facendo clic su di esso.
  3. Tabbing in esso.
  4. Tabbing lontano da esso.
  5. Ctrl+ Ce Ctrl+ Vsulla tastiera.
  6. Fare clic con il tasto destro -> Incolla.
  7. Fare clic con il tasto destro -> Taglia.
  8. Fare clic con il tasto destro -> Copia.
  9. Trascinamento e rilascio di testo da un'altra applicazione.
  10. Modificandolo con Javascript.
  11. Modificandolo con uno strumento di debug, come Firebug.

Mi piacerebbe visualizzarlo usando console.log. È possibile in Javascript / jQuery e, in tal caso, come posso farlo?


La tua domanda così com'è è interessante, ma in un commento hai detto che "Quello che stavo cercando era più un elenco di tutti gli eventi licenziati, quindi so quali sono disponibili per me a cui agganciarmi" - perché non l'hai semplicemente chiederlo? Il doco di MSDN è abbastanza buono per questo: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - non tutti gli eventi elencati sono supportati in tutti i browser, ma se controlli il doco per evento 'on_xyz_' ti dirà "Questo evento è definito in HTML 4.0.", o "Non esiste uno standard pubblico che si applica a questo evento", o qualsiasi altra cosa.
nnnnnn

Risposte:


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

Questo ti darà molte (ma non tutte) le informazioni su se un evento viene attivato ... oltre a codificarlo manualmente in questo modo, non riesco a pensare a nessun altro modo per farlo.


Strano come tu e Shawn entrambi avete scritto male function, e allo stesso modo :).
Daniel T.

1
Sembra che questo metodo vincolerà tutti gli eventi nativi. Immagino che non ci sia modo di visualizzare eventi personalizzati, ad esempio se un plugin ne attiva alcuni personalizzati?
Daniel T.

1
La accetto come risposta, ma la vera risposta alla mia domanda è "sì e no". Quello che stavo cercando era più un elenco di tutti gli eventi che sono stati licenziati, quindi so quali sono disponibili per me a cui agganciarmi. In questo caso, posso vedere quando gli eventi vengono licenziati, ma devo conoscerne il nome in anticipo.
Daniel T.

3
@ Joseph: per quanto riguarda il tuo commento precedente "il focus non è un evento nativo" - um ... sì lo è, uno che esiste da molto prima di jQuery (e prima di Chrome e FF, se è per questo). Inoltre, potresti voler aggiungere blural tuo elenco di eventi.
nnnnnn

3
monitorEvents (document) è la vera risposta
neaumusic

204

Non ho idea del motivo per cui nessuno lo usi ... (forse perché è solo una cosa del webkit)

Console aperta:

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

7
Non copre eventi personalizzati ma aiuta davvero a capire lo stack degli eventi.
Sidonaldson

Questa è la risposta corretta. Non vuoi usare console.log nel codice di produzione, va bene usare la console per gli eventi di debug
neaumusic

1
Googleing monitorEventsnon fornisce informazioni rilevanti su questo, inoltre, sospetto fortemente che sia molto non standard
vsync

3
@vsync prova "monitorEvents" tra virgolette. Fa parte dell'oggetto console ma dipende dal browser. È solo uno strumento di debug in quanto dipende dalla console ... quindi essere standard è irrilevante
Sidonaldson

2
Nota che puoi anche usare qualcosa come monitorEvents($0, 'mouse');per registrare tutti gli eventi di un elemento ispezionato (clic destro> "Ispeziona"). ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo

32

C'è un bel modo generico per usare la raccolta .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);
});

Questo registra ogni evento che è già stato associato all'elemento da jQuery nel momento in cui questo evento specifico viene attivato. Questo codice è stato dannatamente utile per me molte volte.

Btw: Se vuoi vedere ogni possibile evento che viene generato su un oggetto usa firebug: fai semplicemente clic destro sull'elemento DOM nella scheda html e seleziona "Log Events". Ogni evento viene quindi registrato sulla console (questo a volte è un po 'fastidioso perché registra ogni movimento del mouse ...).


18
$('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);
}); 

3
Risposta più completa
leymannx

12

So che la risposta è già stata accettata, ma penso che potrebbe esserci un modo leggermente più affidabile in cui non devi necessariamente conoscere il nome dell'evento in anticipo. Questo funziona solo per gli eventi nativi anche se per quanto ne so, non per quelli personalizzati che sono stati creati dai plugin. Ho scelto di omettere l'uso di jQuery per semplificare un po 'le cose.

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);
    });
  });

Spero che questo aiuti chiunque legga questo.

MODIFICARE

Quindi ho visto un'altra domanda qui che era simile, quindi un altro suggerimento sarebbe quello di fare quanto segue:

monitorEvents(document.getElementById('inputId'));

Questa è la soluzione più elegante del gruppo. Suppongo che sarebbe impossibile scoprire eventi personalizzati poiché questi potrebbero essere emessi tramite dispatchEvent (). Tuttavia, questo copre tutto il resto in un bit di codice compatto e privo di dipendenze.
Roberto

10

Vecchio filo, lo so. Avevo bisogno anche di qualcosa per monitorare gli eventi e ho scritto questa soluzione molto pratica (eccellente). Puoi monitorare tutti gli eventi con questo hook (nella programmazione di Windows questo è chiamato hook). Questo hook non influisce sul funzionamento del software / programma.

Nel registro della console puoi vedere qualcosa del genere:

registro della console

Spiegazione di ciò che vedi:

Nel registro della console vedrai tutti gli eventi che selezioni (vedi sotto "come usare" ) e mostra il tipo di oggetto, classname (s), id, <: name of function>, <: eventname>. La formattazione degli oggetti è simile a css.

Quando fai clic su un pulsante o su qualsiasi evento associato, lo vedrai nel registro della console.

Il codice che ho scritto:

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;
    };
   }
}

Esempi di come usarlo:

Monitorare tutti gli eventi:

setJQueryEventHandlersDebugHooks();

Monitora solo tutti i trigger:

setJQueryEventHandlersDebugHooks(true,false,false);

Monitora solo tutti gli eventi ON:

setJQueryEventHandlersDebugHooks(false,true,false);

Monitora solo disassociazione di tutti gli OFF:

setJQueryEventHandlersDebugHooks(false,false,true);

Osservazioni / Avviso:

  • Usalo solo per il debug, spegnilo quando lo usi nella versione finale del prodotto
  • Se vuoi vedere tutti gli eventi, devi chiamare questa funzione direttamente dopo che jQuery è stato caricato
  • Se vuoi vedere solo meno eventi, puoi chiamare la funzione nel momento in cui ne hai bisogno
  • Se vuoi eseguirlo automaticamente, place () (); intorno alla funzione

Spero che sia d'aiuto! ;-)


Ciao @AmirFo, grazie per aver provato. Poiché non fornisci alcun esempio di ciò che hai fatto, non è possibile vedere se il problema è nel tuo codice o nel mio. Poiché ci sono altri che hanno utilizzato questo esempio con successo, è possibile che tu abbia fatto qualcosa di sbagliato. Hai verificato la presenza di errori nel codice?
Codebeat

Non ci sono stati errori. Ho attivato alcuni eventi, ma nella console non è apparso alcun registro! Sto usando l'ultima versione di Chrome in Ubuntu, Linux.
Amir Fo

@AmirFo: l'hai provato anche in Firefox? Quale versione di jQuery?
Codebeat

@AmirFo: come hai attivato gli eventi? Hai associato degli eventi agli elementi DOM prima di attivarlo?
Codebeat

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
  }
});

1
Puoi dare qualche informazione in più su come funziona e cosa fa esattamente? Come posso collegarlo a un elemento?
Josiah

Questo script modifica HTMLElement.prototype.addEventListenere probabilmente non dovrebbe essere utilizzato in produzione, ma è già stato di grande aiuto per me per scopi di debug.
Günter Zöchbauer

1
Questo non funziona con 1 elemento, funziona per TUTTI LORO. Attinge al gestore degli eventi della finestra e ascolta tutto ciò che accade. Funziona con gestori di eventi nativi e jQuery.
Robert Plummer

2

Aggiungilo alla pagina e nessun'altra preoccupazione, gestirà il resto per te:

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

Puoi anche usare console.log ('Input event:' + e.type) per renderlo più semplice.


3
Strano come tu e Joseph entrambi avete scritto male function, e allo stesso modo :).
Daniel T.

lol, hey ... aveva alcune scritte e ho avuto un miglioramento. ;)
Shawn Khameneh

1
Non permettermi di commentare l'altra risposta, puoi usare .data ("events") per ottenere l'elenco degli eventi.
Shawn Khameneh

Come funziona? Ho provato $('input').data('events')e ritorna indefinito.
Daniel T.

Ciò restituirà gli eventi associati correnti, che includono eventi personalizzati. Se nessun evento è associato, restituirà undefined.
Shawn Khameneh

1

FASE 1: Controllare il eventsper HTML elementil developer console:

inserisci qui la descrizione dell'immagine

FASE 2: ascolta ciò eventsche vogliamo catturare:

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

In bocca al lupo...


1

Di recente ho trovato e modificato questo frammento di un post SO esistente che non sono stato in grado di ritrovare ma l'ho trovato molto 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

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'))

Questo utilizza un po 'di ES6 per la bellezza, ma può essere facilmente tradotto anche per i browser legacy. Nella funzione allegata ai listener di eventi, attualmente sta solo disconnettendo il tipo di evento che si è verificato ma quiè dove puoi stampare informazioni aggiuntive, o usando un caso switch sul e.type, puoi stampare solo informazioni su eventi specifici


0

Ecco un modo non jquery per monitorare gli eventi nella console con il tuo codice e senza l'uso di monitorEvents () perché funziona solo nella Console per gli sviluppatori di Chrome. Puoi anche scegliere di non monitorare determinati eventi modificando l'array 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.