Как вы регистрируете все события, запускаемые элементом в jQuery?


96

Я хотел бы видеть все события, запускаемые полем ввода, когда пользователь взаимодействует с ним. Сюда входят такие вещи, как:

  1. Щелкнув по нему.
  2. Щелкнув по нему.
  3. Включаемся в него.
  4. Переход от него.
  5. Ctrl+ Cи Ctrl+ Vна клавиатуре.
  6. Щелкните правой кнопкой мыши -> Вставить.
  7. Щелкните правой кнопкой мыши -> Вырезать.
  8. Щелкните правой кнопкой мыши -> Копировать.
  9. Перетаскивание текста из другого приложения.
  10. Модификация с помощью Javascript.
  11. Измените его с помощью инструмента отладки, такого как Firebug.

Я хотел бы отобразить его с помощью console.log. Возможно ли это в Javascript / jQuery, и если да, то как мне это сделать?


Ваш вопрос как таковой интересен, но вы сказали в комментарии, что «то, что я искал, было скорее списком всех запускаемых событий, поэтому я знаю, какие из них доступны для меня» - почему вы просто не спроси это? Документ MSDN очень хорош для этого: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - не все перечисленные события поддерживаются во всех браузерах, но если вы проверите doco для event 'on_xyz_' он сообщит вам: «Это событие определено в HTML 4.0.», или «Нет общедоступного стандарта, который применяется к этому событию», или что-то еще.
nnnnnn

Ответы:


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

Это даст вам много (но не всю) информации о том, запускается ли событие ... кроме ручного кодирования его таким образом, я не могу придумать другого способа сделать это.


Странно, как вы и Шон написали с ошибками function, причем одинаково :).
Дэниел Т.

1
Похоже, этот метод свяжет все собственные события. Я предполагаю, что нет возможности отображать пользовательские события, например, если плагин запускает некоторые пользовательские?
Дэниел Т.

2
Я принимаю это как ответ, но настоящий ответ на мой вопрос - «да и нет». То, что я искал, было скорее списком всех запущенных событий, чтобы я знал, какие из них доступны для меня. В этом случае я могу видеть, когда запускаются события, но я должен знать его название заранее.
Дэниел Т.

3
@Joseph: относительно вашего предыдущего комментария «focus is not native event» - ммм ... да, это такое, которое существовало задолго до jQuery (и до Chrome и FF, если на то пошло). Кроме того, вы можете добавить blurв свой список событий.
nnnnnn

3
monitorEvents (документ) - настоящий ответ
neaumusic

210

Я понятия не имею, почему никто не использует это ... (может быть, потому, что это всего лишь вещь webkit)

Открытая консоль:

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
Он не охватывает настраиваемые события, но действительно помогает понять стек событий.
sidonaldson

Это правильный ответ. Вы не хотите использовать console.log в производственном коде, это нормально использовать консоль для отладки событий
neaumusic

1
Googleing не monitorEventsдает соответствующей информации по этому поводу , также я очень подозреваю, что это очень нестандартно
vsync

3
@vsync попробуйте "monitorEvents" в кавычках. Это часть объекта консоли, но зависит от браузера. Это всего лишь инструмент отладки, поскольку он зависит от консоли ... так что стандарт не имеет значения
Сидональдсон

2
Обратите внимание, что вы также можете использовать что-то вроде monitorEvents($0, 'mouse');регистрации всех событий проверяемого (щелкните правой кнопкой мыши> «Проверить») элемента. ( briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo

32

Есть хороший общий способ использования коллекции .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);
});

Это регистрирует каждое событие, которое уже было привязано к элементу jQuery в момент запуска этого конкретного события. Этот код много раз был мне чертовски полезен.

Кстати: если вы хотите видеть каждое возможное событие, запускаемое для объекта, используйте firebug: просто щелкните правой кнопкой мыши элемент DOM на вкладке html и отметьте «Журнал событий». Затем каждое событие записывается в консоль (иногда это немного раздражает, потому что регистрируется каждое движение мыши ...).


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
Самый полный ответ
leymannx

12

Я знаю, что ответ на этот вопрос уже принят, но я думаю, что может быть более надежный способ, при котором вам не обязательно заранее знать название события. Это работает только для собственных событий, хотя, насколько мне известно, не для пользовательских событий, созданных плагинами. Я решил не использовать jQuery, чтобы немного упростить задачу.

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

Надеюсь, это поможет любому, кто это читает.

РЕДАКТИРОВАТЬ

Итак, я увидел здесь еще один похожий вопрос, поэтому другим предложением было бы сделать следующее:

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

Это самое элегантное решение из всех. Я полагаю, что было бы невозможно обнаружить пользовательские события, поскольку они могут быть отправлены через dispatchEvent (). Тем не менее, это охватывает все остальное в компактном, свободном от зависимостей фрагменте кода.
Роберто

10

Старая ветка, я знаю. Мне тоже нужно было что-то для отслеживания событий, и я написал это очень удобное (отличное) решение. Вы можете отслеживать все события с помощью этой ловушки (в программировании Windows это называется ловушкой). Этот хук не влияет на работу вашего программного обеспечения / программы.

В журнале консоли вы можете увидеть что-то вроде этого:

журнал консоли

Объяснение того, что вы видите:

В журнале консоли вы увидите все выбранные вами события (см. Ниже «как использовать» ) и покажите тип объекта, имя (а) класса, идентификатор, <: имя функции>, <: имя события>. Форматирование объектов похоже на css.

Когда вы нажимаете кнопку или любое другое связанное событие, вы увидите его в журнале консоли.

Код, который я написал:

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

Примеры использования:

Следите за всеми событиями:

setJQueryEventHandlersDebugHooks();

Только отслеживать все триггеры:

setJQueryEventHandlersDebugHooks(true,false,false);

Мониторинг только всех событий ON:

setJQueryEventHandlersDebugHooks(false,true,false);

Мониторинг всех отключенных только отключений:

setJQueryEventHandlersDebugHooks(false,false,true);

Примечания / уведомление:

  • Используйте это только для отладки, отключите при использовании в финальной версии продукта.
  • Если вы хотите видеть все события, вы должны вызвать эту функцию сразу после загрузки jQuery.
  • Если вы хотите видеть меньше событий, вы можете вызвать функцию в нужное время.
  • Если вы хотите выполнить его автоматически, place () (); вокруг функции

Надеюсь, это поможет! ;-)


Привет @AmirFo, спасибо за попытку. Поскольку вы не приводите никаких примеров того, что вы сделали, невозможно увидеть, в вашем или моем коде проблема. Поскольку есть другие, которые успешно использовали этот пример, возможно, вы сделали что-то не так. Вы проверяли свой код на наличие ошибок?
Codebeat

Ошибок не было. Запустил какие-то события, но в консоли не появилось логов! Я использую последнюю версию chrome в ubuntu, linux.
Амир Фо,

@AmirFo: Вы пробовали это и в Firefox? Какая версия jQuery?
Codebeat

@AmirFo: Как вы запустили события? Привязывали ли вы какие-либо события к элементам DOM перед их запуском?
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
Не могли бы вы дать дополнительную информацию о том, как это работает и для чего именно? Как я могу прикрепить его к элементу?
Джозия

Этот скрипт изменяет HTMLElement.prototype.addEventListenerи, вероятно, не должен использоваться в продакшене, но он уже очень помог мне в целях отладки.
Günter Zöchbauer

1
Это не работает с одним элементом, это работает для ВСЕХ НИХ. Он подключается к обработчику событий окна и слушает все, что происходит. Он работает с собственными обработчиками событий и jQuery.
Роберт Пламмер

2

Просто добавьте это на страницу, и больше никаких забот, все остальное сделает за вас:

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

Вы также можете использовать console.log ('Input event:' + e.type), чтобы упростить задачу.


3
Странно, как вы и Джозеф написали с ошибками function, причем одинаково :).
Дэниел Т.

лол, эй ... он кое-что написал, и у меня было улучшение. ;)
Shawn Khameneh

1
Не позвольте мне прокомментировать другой ответ, вы можете использовать .data («события»), чтобы получить список событий.
Шон Хамене

Как это работает? Я пробовал, $('input').data('events')и он возвращает undefined.
Дэниел Т.

Это вернет текущие связанные события, включая настраиваемые события. Если никакие события не связаны, он вернет undefined.
Шон Хамене

1

ШАГ 1: Проверьте eventsдля HTML elementна developer console:

введите описание изображения здесь

ШАГ 2: Слушайте то, что eventsмы хотим записать:

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

Удачи...


1

Я недавно нашел и изменил этот фрагмент из существующего сообщения SO, который мне не удалось найти снова, но я нашел его очень полезным

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

Здесь для придания привлекательности используется немного ES6, но его также легко перевести для устаревших браузеров. В функции, прикрепленной к прослушивателям событий, в настоящее время просто регистрируется, какое событие произошло, но именно здесь вы можете распечатать дополнительную информацию или, используя случай переключения e.type, вы можете распечатать информацию только о конкретных событиях.


0

Вот способ отслеживания событий в консоли с помощью вашего кода и без использования monitorEvents () без использования jquery, потому что он работает только в консоли разработчика Chrome. Вы также можете отказаться от отслеживания определенных событий, отредактировав массив 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.