Як реєструвати всі події, запущені елементом у jQuery?


95

Я хотів би бачити всі події, що запускаються полем введення, коли користувач взаємодіє з ним. Це включає такі речі, як:

  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 - не всі перелічені події підтримуються у всіх браузерах, але якщо ви перевірите доко на наявність подія 'on_xyz_', вона скаже вам "Ця подія визначена в HTML 4.0.", або "Немає загальнодоступного стандарту, який застосовується до цієї події", або що завгодно.
nnnnnn

Відповіді:


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

Це дасть вам багато (але не всю) інформації про те, якщо подія запускається ... крім ручного кодування, як це, я не можу придумати жодного іншого способу зробити це.


Дивно, як ви з Шоном неправильно написали function, і однаково :).
Даніель Т.

1
Схоже, цей метод пов’язує всі власні події. Я здогадуюсь, що немає можливості відобразити власні події, наприклад, якщо плагін запускає деякі власні?
Даніель Т.

2
Я приймаю це як відповідь, але справжня відповідь на моє запитання - "так і ні". Я шукав більше списку всіх подій, які запускаються, тому я знаю, які з них доступні для мене. У цьому випадку я бачу, коли події запускаються, але заздалегідь я повинен знати його назву.
Даніель Т.

3
@Joseph: щодо вашого попереднього коментаря "фокус - це не рідна подія" - гм ... так, це той, який існував задовго до jQuery (і, перш за все, до Chrome та FF). Крім того, ви можете додати blurдо свого списку подій.
nnnnnn

3
monitorEvents (документ) - справжня відповідь
neaumusic

206

Я не уявляю, чому ніхто цим не користується ... (можливо, тому, що це лише веб-набір)

Відкрита консоль:

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" у лапки. Це частина консольного об'єкта, але залежить від браузера. Це лише інструмент налагодження, оскільки це залежить від консолі ... тому бути стандартним не має значення
sidonaldson

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
  • Якщо ви хочете бачити лише менше подій, ви можете зателефонувати функції у потрібний час
  • Якщо ви хочете виконати це автоматично, помістіть () (); навколо функції

Сподіваюся, це допоможе! ;-)


Привіт @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
Це не працює з 1 елементом, воно працює для ВСІХ ІХ. Він торкається обробника подій вікна і прослуховує все, що відбувається. Він працює з власними обробниками подій та jQuery.
Роберт Пламмер,

2

Просто додайте це на сторінку, і будь-яких інших турбот, вам допоможе відпочинок:

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

Ви також можете використовувати console.log ('Вхідна подія:' + e.type), щоб полегшити.


3
Дивно, як ви з Джозефом неправильно написали function, і однаково :).
Даніель Т.

ха-ха, ей ... у нього щось виписали, а у мене покращення. ;)
Шон Хамене

1
Не дозволяйте мені коментувати іншу відповідь, ви можете використовувати .data ("події"), щоб отримати список подій.
Шон Хамене

Як це працює? Я спробував, $('input').data('events')і він повертається невизначеним.
Даніель Т.

Це поверне поточні пов'язані події, що включає власні події. Якщо жодна подія не пов'язана, вона повернеться невизначеною.
Шон Хамене

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

Ось не jquery спосіб відстежувати події в консолі за допомогою коду і без використання monitorEvents (), оскільки це працює лише в консолі розробника 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.