Wie protokollieren Sie alle Ereignisse, die von einem Element in jQuery ausgelöst wurden?


93

Ich möchte alle Ereignisse sehen, die von einem Eingabefeld ausgelöst werden , wenn ein Benutzer damit interagiert. Dies beinhaltet Dinge wie:

  1. Klicken Sie darauf.
  2. Klicken Sie darauf.
  3. Tabbing hinein.
  4. Tabbing weg von ihm.
  5. Ctrl+ Cund Ctrl+ Vauf der Tastatur.
  6. Rechtsklick -> Einfügen.
  7. Rechtsklick -> Ausschneiden.
  8. Rechtsklick -> Kopieren.
  9. Ziehen und Ablegen von Text aus einer anderen Anwendung.
  10. Ändern mit Javascript.
  11. Ändern Sie es mit einem Debug-Tool wie Firebug.

Ich möchte es mit anzeigen console.log. Ist dies in Javascript / jQuery möglich und wenn ja, wie mache ich das?


Ihre Frage ist interessant, aber Sie sagten in einem Kommentar: "Was ich gesucht habe, war eher eine Liste aller Ereignisse, die abgefeuert werden, damit ich weiß, welche für mich verfügbar sind" - warum haben Sie es nicht einfach getan? Frag das? Das Dokument von MSDN ist dafür ziemlich gut geeignet : msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - nicht alle aufgelisteten Ereignisse werden in allen Browsern unterstützt, aber wenn Sie das Dokument auf überprüfen Ereignis 'on_xyz_' sagt Ihnen "Dieses Ereignis ist in HTML 4.0 definiert." oder "Es gibt keinen öffentlichen Standard, der für dieses Ereignis gilt" oder was auch immer.
nnnnnn

Antworten:


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

Dadurch erhalten Sie viele (aber nicht alle) Informationen darüber, ob ein Ereignis ausgelöst wird. Abgesehen davon, dass Sie es manuell so codieren, fällt mir keine andere Möglichkeit ein, dies zu tun.


Seltsam, wie du und Shawn beide falsch geschrieben functionhaben und auf die gleiche Weise :).
Daniel T.

1
Es sieht so aus, als würde diese Methode alle nativen Ereignisse binden. Ich vermute, es gibt keine Möglichkeit, benutzerdefinierte Ereignisse anzuzeigen, beispielsweise wenn ein Plugin einige benutzerdefinierte Ereignisse auslöst.
Daniel T.

1
Ich akzeptiere dies als Antwort, aber die eigentliche Antwort auf meine Frage lautet "Ja und Nein". Was ich suchte, war eher eine Liste aller Ereignisse, die ausgelöst wurden, damit ich weiß, welche für mich verfügbar sind. In diesem Fall kann ich sehen, wann die Ereignisse ausgelöst werden, aber ich muss den Namen vorher wissen.
Daniel T.

3
@Joseph: In Bezug auf Ihren früheren Kommentar "Fokus ist kein natives Ereignis" - ähm ... ja, eines, das es schon lange vor jQuery (und vor Chrome und FF) gibt. Möglicherweise möchten Sie auch blurzu Ihrer Ereignisliste hinzufügen .
nnnnnn

3
monitorEvents (Dokument) ist die wahre Antwort
neaumusic

203

Ich habe keine Ahnung, warum niemand dies verwendet ... (vielleicht weil es nur eine Webkit-Sache ist)

Konsole öffnen:

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
Es werden keine benutzerdefinierten Ereignisse behandelt, aber es hilft wirklich, den Ereignisstapel zu verstehen.
Sidonaldson

Dies ist die richtige Antwort. Sie möchten console.log nicht im Produktionscode verwenden, es ist in Ordnung, die Konsole zum Debuggen von Ereignissen zu verwenden
neaumusic

1
Googleing monitorEventsgibt keine relevanten Informationen dazu, außerdem vermute ich sehr, dass dies sehr
unüblich ist

3
@vsync versuchen Sie "monitorEvents" in Anführungszeichen. Es ist Teil des Konsolenobjekts, aber vom Browser abhängig. Es ist nur ein Debugging-Tool, da es von der Konsole abhängt. Standard zu sein ist also irrelevant
Sidonaldson

2
Beachten Sie, dass Sie auch monitorEvents($0, 'mouse');alle Ereignisse eines inspizierten Elements (Rechtsklick> "Inspizieren") protokollieren können. ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
Rinogo

32

Es gibt eine nette generische Möglichkeit, die .data-Sammlung ('events') zu verwenden:

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

Dies protokolliert jedes Ereignis, das bereits von jQuery an das Element gebunden wurde, sobald dieses bestimmte Ereignis ausgelöst wird. Dieser Code war für mich viele Male verdammt hilfreich.

Übrigens: Wenn Sie sehen möchten, dass jedes mögliche Ereignis auf ein Objekt ausgelöst wird, verwenden Sie firebug: Klicken Sie einfach mit der rechten Maustaste auf das DOM-Element in der HTML-Registerkarte und aktivieren Sie "Ereignisse protokollieren". Jedes Ereignis wird dann in der Konsole protokolliert (dies ist manchmal etwas ärgerlich, da jede Mausbewegung protokolliert wird ...).


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
Vollständigste Antwort
Leymannx

12

Ich weiß, dass die Antwort darauf bereits akzeptiert wurde, aber ich denke, es gibt einen etwas zuverlässigeren Weg, bei dem Sie den Namen des Ereignisses nicht unbedingt vorher kennen müssen. Dies funktioniert meines Wissens nur für native Ereignisse, nicht für benutzerdefinierte Ereignisse, die von Plugins erstellt wurden. Ich habe mich dafür entschieden, die Verwendung von jQuery wegzulassen, um die Dinge ein wenig zu vereinfachen.

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

Ich hoffe das hilft jedem, der das liest.

BEARBEITEN

Ich habe hier eine andere Frage gesehen , die ähnlich war. Ein weiterer Vorschlag wäre, Folgendes zu tun:

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

Dies ist die eleganteste Lösung der Reihe. Ich nehme an, es wäre unmöglich, benutzerdefinierte Ereignisse zu erkennen, da diese über dispatchEvent () ausgegeben werden könnten. Dies deckt jedoch alles andere in einem kompakten, abhängigkeitsfreien Code ab.
Roberto

10

Alter Faden, ich weiß. Ich brauchte auch etwas, um Ereignisse zu überwachen und schrieb diese sehr praktische (ausgezeichnete) Lösung. Sie können alle Ereignisse mit diesem Hook überwachen (in der Windows-Programmierung wird dies als Hook bezeichnet). Dieser Hook wirkt sich nicht auf den Betrieb Ihrer Software / Ihres Programms aus.

Im Konsolenprotokoll sehen Sie ungefähr Folgendes:

Konsolenprotokoll

Erklärung dessen, was Sie sehen:

Im Konsolenprotokoll werden alle von Ihnen ausgewählten Ereignisse angezeigt (siehe unten "Verwendung"). ) und der Objekttyp, Klassenname (n), ID, <: Name der Funktion>, <: Ereignisname> angezeigt. Die Formatierung der Objekte ist CSS-ähnlich.

Wenn Sie auf eine Schaltfläche oder ein anderes gebundenes Ereignis klicken, wird es im Konsolenprotokoll angezeigt.

Der Code, den ich geschrieben habe:

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

Beispiele zur Verwendung:

Überwachen Sie alle Ereignisse:

setJQueryEventHandlersDebugHooks();

Überwachen Sie nur alle Trigger:

setJQueryEventHandlersDebugHooks(true,false,false);

Überwachen Sie nur alle EIN-Ereignisse:

setJQueryEventHandlersDebugHooks(false,true,false);

Überwachen Sie nur alle AUS-Entbindungen:

setJQueryEventHandlersDebugHooks(false,false,true);

Anmerkungen / Hinweis:

  • Verwenden Sie diese Option nur zum Debuggen. Deaktivieren Sie sie, wenn Sie sie in der endgültigen Produktversion verwenden
  • Wenn Sie alle Ereignisse sehen möchten, müssen Sie diese Funktion direkt nach dem Laden von jQuery aufrufen
  • Wenn Sie nur weniger Ereignisse sehen möchten, können Sie die Funktion zum gewünschten Zeitpunkt aufrufen
  • Wenn Sie es automatisch ausführen möchten, platzieren Sie () (); um Funktion

Ich hoffe es hilft! ;-);


Hallo @AmirFo, danke, dass du es versucht hast. Da Sie keine Beispiele für Ihre Aktivitäten angeben, können Sie nicht feststellen, ob das Problem in Ihrem oder meinem Code liegt. Da es andere gibt, die dieses Beispiel erfolgreich verwendet haben, ist es möglich, dass Sie etwas falsch gemacht haben. Haben Sie Ihren Code auf Fehler überprüft?
Codebeat

Es gab keine Fehler. Ich habe einige Ereignisse ausgelöst, aber es wurden keine Protokolle in der Konsole angezeigt! Ich verwende die neueste Version von Chrome in Ubuntu, Linux.
Amir Fo

@AmirFo: Hast du es auch in Firefox versucht? Welche Version von jQuery?
Codebeat

@AmirFo: Wie hast du die Ereignisse ausgelöst? Haben Sie Ereignisse an DOM-Elemente gebunden, bevor Sie sie ausgelöst haben?
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
Können Sie weitere Informationen darüber geben, wie dies funktioniert und was es genau tut? Wie kann ich es an ein Element anhängen?
Josiah

Dieses Skript wurde geändert HTMLElement.prototype.addEventListenerund sollte wahrscheinlich nicht in der Produktion verwendet werden, aber es war bereits eine große Hilfe für mich beim Debuggen.
Günter Zöchbauer

1
Dies funktioniert nicht mit 1 Element, sondern für ALLE. Es greift auf den Ereignishandler des Fensters zu und hört alles ab, was passiert. Es funktioniert mit nativen Ereignishandlern und jQuery.
Robert Plummer

2

Fügen Sie dies einfach der Seite hinzu und keine anderen Sorgen erledigen die Ruhe für Sie:

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

Sie können auch console.log ('Eingabeereignis:' + e.type) verwenden, um dies zu vereinfachen.


3
Seltsam, wie du und Joseph beide falsch geschrieben functionhaben und auf die gleiche Weise :).
Daniel T.

lol, hey ... er hatte einige ausgeschrieben und ich hatte eine Verbesserung. ;)
Shawn Khameneh

1
Lassen Sie mich die andere Antwort nicht kommentieren. Sie können .data ("Ereignisse") verwenden, um die Liste der Ereignisse abzurufen.
Shawn Khameneh

Wie funktioniert es? Ich habe es versucht $('input').data('events')und es wird undefiniert zurückgegeben.
Daniel T.

Dadurch werden die aktuell gebundenen Ereignisse zurückgegeben, einschließlich benutzerdefinierter Ereignisse. Wenn keine Ereignisse gebunden sind, wird undefiniert zurückgegeben.
Shawn Khameneh

1

Schritt 1: Überprüfen Sie die eventsfür eine HTML elementauf der developer console:

Geben Sie hier die Bildbeschreibung ein

SCHRITT 2: Hören Sie sich das an, was eventswir erfassen möchten:

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

Viel Glück...


1

Ich habe kürzlich dieses Snippet aus einem vorhandenen SO-Beitrag gefunden und geändert, den ich nicht wieder finden konnte, aber ich fand es sehr nützlich

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

Dies verwendet ein wenig ES6 für die Schönheit, kann aber auch für ältere Browser leicht übersetzt werden. In der Funktion, die an die Ereignis-Listener angehängt ist, wird derzeit nur protokolliert, welche Art von Ereignis aufgetreten ist. Hier können Sie jedoch zusätzliche Informationen ausdrucken oder mithilfe eines Schaltergehäuses e.typenur Informationen zu bestimmten Ereignissen drucken


0

Hier ist eine nicht abfragbare Möglichkeit, Ereignisse in der Konsole mit Ihrem Code und ohne die Verwendung von monitorEvents () zu überwachen, da dies nur in der Chrome Developer Console funktioniert. Sie können auch festlegen, dass bestimmte Ereignisse nicht überwacht werden, indem Sie das Array no_watch bearbeiten.

    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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.