Jak logować wszystkie zdarzenia wywołane przez element w jQuery?


96

Chciałbym zobaczyć wszystkie zdarzenia wywołane przez pole wejściowe, gdy użytkownik wchodzi z nim w interakcję. Obejmuje to takie rzeczy, jak:

  1. Klikając na to.
  2. Klikając to.
  3. Wchodząc w to.
  4. Odsuwam się od tego.
  5. Ctrl+ Ci Ctrl+ Vna klawiaturze.
  6. Kliknij prawym przyciskiem myszy -> Wklej.
  7. Kliknij prawym przyciskiem myszy -> Wytnij.
  8. Kliknij prawym przyciskiem myszy -> Kopiuj.
  9. Przeciąganie i upuszczanie tekstu z innej aplikacji.
  10. Modyfikowanie go za pomocą JavaScript.
  11. Modyfikowanie go za pomocą narzędzia do debugowania, takiego jak Firebug.

Chciałbym to wyświetlić za pomocą console.log. Czy jest to możliwe w Javascript / jQuery, a jeśli tak, to jak to zrobić?


Twoje pytanie jest interesujące, ale powiedziałeś w komentarzu, że „To, czego szukałem, to raczej lista wszystkich wystrzeliwanych zdarzeń, więc wiem, które z nich są dostępne dla mnie” - dlaczego po prostu nie Zapytaj o to? Dokumentacja MSDN jest całkiem dobra do tego: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - nie wszystkie wymienione zdarzenia są obsługiwane we wszystkich przeglądarkach, ale jeśli sprawdzisz dokumentację pod kątem event 'on_xyz_' powie Ci „To zdarzenie jest zdefiniowane w HTML 4.0.” lub „Nie ma publicznego standardu, który odnosi się do tego wydarzenia” lub cokolwiek innego.
nnnnnn

Odpowiedzi:


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

To da ci wiele (ale nie wszystkie) informacji o tym, czy zdarzenie zostanie uruchomione ... poza ręcznym kodowaniem w ten sposób, nie mogę wymyślić żadnego innego sposobu, aby to zrobić.


Dziwne, jak ty i Shawn popełniliście błąd w pisowni functioniw ten sam sposób :).
Daniel T.,

1
Wygląda na to, że ta metoda wiąże wszystkie zdarzenia natywne. Zgaduję, że nie ma sposobu, aby wyświetlić zdarzenia niestandardowe, na przykład jeśli wtyczka uruchamia niektóre niestandardowe?
Daniel T.,

2
Przyjmuję to jako odpowiedź, ale prawdziwa odpowiedź na moje pytanie brzmi „tak i nie”. To, czego szukałem, to raczej lista wszystkich wystrzeliwanych zdarzeń, więc wiem, które z nich są dostępne dla mnie. W tym przypadku widzę, kiedy dochodzi do wydarzeń, ale muszę wcześniej znać ich nazwę.
Daniel T.

3
@Joseph: odnosząc się do twojego wcześniejszego komentarza "fokus nie jest rodzimym wydarzeniem" - hm ... tak jest, takie, które istniało na długo przed jQuery (a nawet przed Chrome i FF). Możesz także dodać blurwydarzenia do swojej listy wydarzeń.
nnnnnn

3
monitorEvents (dokument) to prawdziwa odpowiedź
neaumusic

210

Nie mam pojęcia, dlaczego nikt tego nie używa ... (może dlatego, że jest to tylko zestaw internetowy)

Otwórz konsolę:

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
Nie obejmuje wydarzeń niestandardowych, ale naprawdę pomaga zrozumieć stos zdarzeń.
sidonaldson

To jest poprawna odpowiedź. Nie chcesz używać console.log w kodzie produkcyjnym, dobrze jest używać konsoli do debugowania zdarzeń
neaumusic

1
Googleing monitorEventsnie daje istotne informacje na ten temat, także, bardzo podejrzewam, że to jest bardzo nietypowe
vsync

3
@vsync spróbuj wpisać „monitorEvents” w cudzysłowie. Jest częścią obiektu konsoli, ale zależy od przeglądarki. To tylko narzędzie do debugowania, ponieważ zależy od konsoli ... więc bycie standardem nie ma znaczenia
sidonaldson

2
Zauważ, że możesz także użyć czegoś takiego jak monitorEvents($0, 'mouse');rejestrowanie wszystkich zdarzeń sprawdzanego elementu (kliknij prawym przyciskiem myszy> „Sprawdź”). ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo

32

Istnieje ładny ogólny sposób korzystania z kolekcji .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);
});

To rejestruje każde zdarzenie, które zostało już powiązane z elementem przez jQuery w momencie uruchomienia tego konkretnego zdarzenia. Ten kod był dla mnie cholernie pomocny wiele razy.

Btw: Jeśli chcesz zobaczyć każde możliwe zdarzenie uruchamiane na obiekcie, użyj firebuga: po prostu kliknij prawym przyciskiem myszy element DOM w zakładce html i zaznacz „Log Events”. Każde zdarzenie jest następnie rejestrowane w konsoli (czasami jest to trochę denerwujące, ponieważ rejestruje każdy ruch myszy ...).


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

3
Najbardziej kompletna odpowiedź
leymannx

12

Wiem, że odpowiedź została już zaakceptowana, ale myślę, że może istnieć nieco bardziej niezawodny sposób, w którym niekoniecznie trzeba wcześniej znać nazwę wydarzenia. Działa to tylko w przypadku wydarzeń natywnych, choć o ile wiem, a nie niestandardowych, które zostały utworzone przez wtyczki. Zdecydowałem się pominąć użycie jQuery, aby trochę uprościć.

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

Mam nadzieję, że pomoże to każdemu, kto to czyta.

EDYTOWAĆ

Widziałem więc tutaj inne pytanie, które było podobne, więc inną sugestią byłoby wykonanie następujących czynności:

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

To najbardziej eleganckie rozwiązanie ze wszystkich. Przypuszczam, że nie byłoby możliwe wykrycie zdarzeń niestandardowych, ponieważ można by je emitować za pośrednictwem metody dispatchEvent (). Jednak obejmuje to wszystko inne w kompaktowym, wolnym od zależności, fragmencie kodu.
Roberto

10

Wiem, stara nić. Potrzebowałem też czegoś do monitorowania wydarzeń i napisałem to bardzo przydatne (doskonałe) rozwiązanie. Możesz monitorować wszystkie zdarzenia za pomocą tego podpięcia (w programowaniu Windows nazywa się to podpięciem). Ten hak nie wpływa na działanie twojego oprogramowania / programu.

W dzienniku konsoli możesz zobaczyć coś takiego:

dziennik konsoli

Wyjaśnienie tego, co widzisz:

W dzienniku konsoli zobaczysz wszystkie wybrane zdarzenia (patrz poniżej „jak używać” ) i pokazany jest typ obiektu, nazwa (y) klasy, identyfikator, <: nazwa funkcji>, <: nazwa zdarzenia>. Formatowanie obiektów jest podobne do CSS.

Kiedy klikniesz przycisk lub jakiekolwiek powiązane zdarzenie, zobaczysz to w dzienniku konsoli.

Kod, który napisałem:

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

Przykłady użycia:

Monitoruj wszystkie zdarzenia:

setJQueryEventHandlersDebugHooks();

Monitoruj tylko wszystkie wyzwalacze:

setJQueryEventHandlersDebugHooks(true,false,false);

Monitoruj tylko zdarzenia ON:

setJQueryEventHandlersDebugHooks(false,true,false);

Monitoruj wszystkie WYŁĄCZONE tylko odłączenia:

setJQueryEventHandlersDebugHooks(false,false,true);

Uwagi / uwaga:

  • Użyj tego tylko do debugowania, wyłącz, gdy używasz w ostatecznej wersji produktu
  • Jeśli chcesz zobaczyć wszystkie zdarzenia, musisz wywołać tę funkcję bezpośrednio po załadowaniu jQuery
  • Jeśli chcesz zobaczyć tylko mniej zdarzeń, możesz wywołać funkcję w czasie, w którym jej potrzebujesz
  • Jeśli chcesz go wykonać automatycznie, umieść () (); wokół funkcji

Mam nadzieję, że to pomoże! ;-)


Cześć @AmirFo, dzięki za próbę. Ponieważ nie podajesz żadnych przykładów tego, co zrobiłeś, nie jest możliwe sprawdzenie, czy problem jest w Twoim kodzie, czy w moim. Ponieważ są inni, którzy z powodzeniem wykorzystali ten przykład, możliwe, że zrobiłeś coś źle. Czy sprawdziłeś kod pod kątem błędów?
Codebeat

Nie było żadnych błędów. Wywołałem pewne zdarzenia, ale w konsoli nie pojawiły się żadne dzienniki! Używam najnowszej wersji Chrome w Ubuntu, Linux.
Amir Fo

@AmirFo: Czy wypróbowałeś to również w Firefoksie? Jaka wersja jQuery?
Codebeat

@AmirFo: W jaki sposób wywołałeś wydarzenia? Czy powiązałeś jakieś zdarzenia z elementami DOM przed ich uruchomieniem?
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
Czy możesz podać więcej informacji o tym, jak to działa i co dokładnie robi? Jak mogę dołączyć go do elementu?
Josiah

Ten skrypt modyfikuje HTMLElement.prototype.addEventListeneri prawdopodobnie nie powinien być używany w produkcji, ale już był dla mnie wielką pomocą przy debugowaniu.
Günter Zöchbauer,

1
To nie działa z jednym elementem, działa dla WSZYSTKICH. Łączy się z programem obsługi zdarzeń okna i nasłuchuje wszystkiego, co się dzieje. Działa z natywnymi programami obsługi zdarzeń i jQuery.
Robert Plummer

2

Po prostu dodaj to do strony i nie martw się, resztę załatwisz:

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

Możesz także użyć console.log ('Zdarzenie wejściowe:' + e.type), aby to ułatwić.


3
Dziwne, jak ty i Joseph popełniliście błąd w pisowni functioniw ten sam sposób :).
Daniel T.,

lol, hej ... miał kilka napisanych i miałem poprawę. ;)
Shawn Khameneh

1
Nie pozwolę sobie skomentować innej odpowiedzi, możesz użyć .data („wydarzenia”), aby pobrać listę wydarzeń.
Shawn Khameneh

Jak to działa? Próbowałem $('input').data('events')i wraca niezdefiniowany.
Daniel T.

Spowoduje to zwrócenie bieżących powiązanych zdarzeń, w tym zdarzeń niestandardowych. Jeśli żadne zdarzenia nie są powiązane, zwróci wartość undefined.
Shawn Khameneh,

1

KROK 1: Sprawdź, czy eventsdla HTML elementna developer console:

wprowadź opis obrazu tutaj

KROK 2: Posłuchaj tego, eventsco chcemy uchwycić:

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

Powodzenia...


1

Niedawno znalazłem i zmodyfikowałem ten fragment z istniejącego posta SO, którego nie mogłem znaleźć ponownie, ale uznałem go za bardzo przydatny

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

Używa to trochę ES6 dla ładności, ale można je łatwo przetłumaczyć również dla starszych przeglądarek. W funkcji dołączonej do detektorów zdarzeń obecnie po prostu wylogowuje się, jakiego rodzaju zdarzenie miało miejsce, ale w tym miejscu można wydrukować dodatkowe informacje lub używając przełącznika w przypadku e.type, można wydrukować tylko informacje o określonych zdarzeniach


0

Oto sposób monitorowania zdarzeń w konsoli za pomocą własnego kodu i bez użycia metody monitorEvents (), który nie jest oparty na jquery, ponieważ działa to tylko w konsoli programisty Chrome. Możesz także zrezygnować z monitorowania niektórych zdarzeń, edytując tablicę 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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.