Como você registra todos os eventos disparados por um elemento no jQuery?

94

Eu gostaria de ver todos os eventos disparados por um campo de entrada conforme um usuário interage com ele. Isso inclui coisas como:

  1. Clicando nele.
  2. Clicando fora dele.
  3. Tabulando para ele.
  4. Tabbing longe dele.
  5. Ctrl+ Ce Ctrl+V no teclado.
  6. Clique com o botão direito -> Colar.
  7. Clique com o botão direito -> Cortar.
  8. Clique com o botão direito -> Copiar.
  9. Arrastar e soltar texto de outro aplicativo.
  10. Modificando com Javascript.
  11. Modificando-o com uma ferramenta de depuração, como Firebug.

Eu gostaria de exibi-lo usando console.log. Isso é possível em Javascript / jQuery e, em caso afirmativo, como faço isso?

Daniel T.
fonte
Sua pergunta é interessante, mas você disse em um comentário que "O que eu estava procurando era mais uma lista de todos os eventos que estão sendo disparados para que eu saiba quais estão disponíveis para eu enganchar" - por que você simplesmente não pergunta isso? O doco do MSDN é muito bom para isso: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - nem todos os eventos listados são suportados em todos os navegadores, mas se você verificar o doco para evento 'on_xyz_' dirá "Este evento é definido em HTML 4.0.", ou "Não existe um padrão público que se aplique a este evento", ou qualquer outra coisa.
nnnnnn
2
A resposta - stackoverflow.com/questions/7439570/…
neaumusic

Respostas:

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

Isso lhe dará muitas (mas não todas) as informações sobre se um evento é disparado ... além de codificá-lo manualmente assim, não consigo pensar em nenhuma outra maneira de fazer isso.

Joseph Marikle
fonte
Estranho como você e Shawn escreveram mal function, e da mesma forma :).
Daniel T.
1
Parece que esse método vinculará todos os eventos nativos. Estou supondo que não há maneira de exibir eventos personalizados, por exemplo, se um plugin dispara alguns personalizados?
Daniel T.
1
Estou aceitando isso como a resposta, mas a verdadeira resposta à minha pergunta é "sim e não". O que eu procurava era mais uma lista de todos os eventos que estão sendo disparados para que eu saiba quais estão disponíveis para eu me conectar. Nesse caso, posso ver quando os eventos estão sendo disparados, mas preciso saber o nome de antemão.
Daniel T.
3
@Joseph: em relação ao seu comentário anterior "o foco não é um evento nativo" - hum ... sim, é, um que existe desde muito antes do jQuery (e antes do Chrome e do FF, por falar nisso). Além disso, você pode querer adicionar blurà sua lista de eventos.
nnnnnn
3
monitorEvents (documento) é a resposta real
neaumusic
204

Não tenho ideia de por que ninguém usa isso ... (talvez porque seja apenas uma coisa de webkit)

Abra o 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
fonte
7
Não cobre eventos personalizados, mas realmente ajuda a entender a pilha de eventos.
Sidonaldson
Essa é a resposta correta. Você não quer usar console.log no código de produção, não há problema em usar o console para eventos de depuração
neaumusic
1
O Googleing monitorEventsnão fornece informações relevantes sobre isso, também, eu suspeito que isso seja muito fora do padrão
vsync
3
@vsync tente "monitorEvents" entre aspas. Faz parte do objeto do console, mas depende do navegador. É apenas uma ferramenta de depuração, pois depende do console ... então ser padrão é irrelevante
Sidonaldson
2
Observe que você também pode usar algo como monitorEvents($0, 'mouse');registrar todos os eventos de um elemento inspecionado (clique com o botão direito> "Inspecionar"). ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo,
32

Existe uma boa maneira genérica de usar a coleção .data ('eventos'):

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

Isso registra todos os eventos que já foram vinculados ao elemento por jQuery no momento em que esse evento específico é acionado. Este código foi muito útil para mim muitas vezes.

A propósito: se você quiser ver todos os eventos possíveis sendo disparados em um objeto, use firebug: apenas clique com o botão direito do mouse no elemento DOM na guia html e marque "Log Events". Cada evento é então registrado no console (isso às vezes é um pouco chato porque registra cada movimento do mouse ...).

Simon
fonte
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);
}); 
maudulus
fonte
3
Resposta mais completa
leymannx
12

Eu sei que a resposta já foi aceita para isso, mas acho que pode haver uma maneira um pouco mais confiável, onde você não precisa necessariamente saber o nome do evento de antemão. Isso só funciona para eventos nativos, embora eu saiba, não para eventos personalizados que foram criados por plug-ins. Optei por omitir o uso de jQuery para simplificar um pouco as coisas.

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

Espero que isso ajude quem ler isso.

EDITAR

Então, eu vi outra pergunta aqui que era semelhante, então outra sugestão seria fazer o seguinte:

monitorEvents(document.getElementById('inputId'));
Patrick Roberts
fonte
Esta é a solução mais elegante do grupo. Suponho que seja impossível descobrir eventos personalizados, pois eles podem ser emitidos por meio de dispatchEvent (). No entanto, isso cobre todo o resto em um bit de código compacto e livre de dependências.
Roberto
10

Tópico antigo, eu sei. Eu precisava também de algo para monitorar eventos e escrevi esta solução muito útil (excelente). Você pode monitorar todos os eventos com este gancho (na programação do Windows, isso é chamado de gancho). Este gancho não afeta a operação do seu software / programa.

No log do console, você pode ver algo assim:

log do console

Explicação do que você vê:

No log do console você verá todos os eventos que selecionar (veja abaixo "como usar" ) e mostra o tipo de objeto, nome (s) de classe, id, <: nome da função>, <: nome do evento>. A formatação dos objetos é semelhante a css.

Ao clicar em um botão ou em qualquer evento vinculado, você o verá no log do console.

O código que escrevi:

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

Exemplos de como usar:

Monitore todos os eventos:

setJQueryEventHandlersDebugHooks();

Monitore apenas todos os gatilhos:

setJQueryEventHandlersDebugHooks(true,false,false);

Monitore todos os eventos ON apenas:

setJQueryEventHandlersDebugHooks(false,true,false);

Monitore todos os desligamentos OFF apenas:

setJQueryEventHandlersDebugHooks(false,false,true);

Observações / Aviso:

  • Use isso apenas para depuração, desligue-o ao usar na versão final do produto
  • Se você quiser ver todos os eventos, você deve chamar esta função diretamente após o jQuery ser carregado
  • Se você quiser ver apenas menos eventos, pode chamar a função na hora que precisar
  • Se você quiser executá-lo automaticamente, coloque () (); em torno da função

Espero que ajude! ;-)

Codebeat
fonte
Olá @AmirFo, obrigado por tentar. Como você não fornece exemplos do que fez, não é possível ver se o problema está no seu código ou no meu. Como há outras pessoas que usaram esse exemplo com sucesso, é possível que você tenha feito algo errado. Você verificou se há erros no seu código?
Codebeat
Não houve erros. Eu disparei alguns eventos, mas nenhum log apareceu no console! Estou usando a versão mais recente do Chrome no Ubuntu, Linux.
Amir Fo
@AmirFo: Você também tentou no Firefox? Qual versão do jQuery?
Codebeat
@AmirFo: Como você desencadeou os eventos? Você vinculou algum evento a elementos DOM antes de acioná-lo?
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
  }
});
Robert Plummer
fonte
1
Você pode dar mais informações sobre como isso funciona e o que faz exatamente? Como posso anexá-lo a um elemento?
Josiah
Este script modifica HTMLElement.prototype.addEventListenere provavelmente não deveria ser usado em produção, mas já foi uma grande ajuda para fins de depuração.
Günter Zöchbauer
1
Isso não funciona com 1 elemento, funciona para TODOS ELES. Ele acessa o manipulador de eventos da janela e ouve tudo o que acontece. Ele funciona com manipuladores de eventos nativos e jQuery.
Robert Plummer
2

Basta adicionar isso à página e sem outras preocupações, cuidarei do resto para você:

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

Você também pode usar console.log ('Evento de entrada:' + e.type) para torná-lo mais fácil.

Shawn Khameneh
fonte
3
Estranho como você e Joseph escreveram mal function, e da mesma forma :).
Daniel T.
lol, hey ... ele tinha algumas escritas e eu tive uma melhora. ;)
Shawn Khameneh
1
Não me deixe comentar a outra resposta, você pode usar .data ("eventos") para pegar a lista de eventos.
Shawn Khameneh
Como funciona? Tentei $('input').data('events')e retorna indefinido.
Daniel T.
Isso retornará os eventos de limite atuais, que incluem eventos personalizados. Se nenhum evento for vinculado, ele retornará indefinido.
Shawn Khameneh
1

PASSO 1: Verifique se eventshá um HTML elementno developer console:

insira a descrição da imagem aqui

ETAPA 2: Ouça o eventsque queremos capturar:

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

Boa sorte...

Akash
fonte
1

Recentemente encontrei e modifiquei este trecho de um post existente do SO que não consegui encontrar novamente, mas achei muito útil

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

Isso usa um pouco de ES6 para beleza, mas pode ser facilmente traduzido para navegadores legados também. Na função anexada aos ouvintes de evento, atualmente está apenas registrando o tipo de evento ocorrido, mas é aqui que você pode imprimir informações adicionais ou, usando um caso de switch no e.type, você só pode imprimir informações sobre eventos específicos

Lisa
fonte
0

Esta é uma maneira não jquery de monitorar eventos no console com o seu código e sem o uso de monitorEvents () porque isso só funciona no Chrome Developer Console. Você também pode optar por não monitorar certos eventos editando o 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
Jeff Baker
fonte