Bagaimana Anda mencatat semua peristiwa yang dipicu oleh elemen di jQuery?


95

Saya ingin melihat semua peristiwa yang dipicu oleh bidang masukan saat pengguna berinteraksi dengannya. Ini termasuk hal-hal seperti:

  1. Mengkliknya.
  2. Mengkliknya.
  3. Menabraknya.
  4. Menjauh darinya.
  5. Ctrl+ Cdan Ctrl+ Vdi keyboard.
  6. Klik kanan -> Tempel.
  7. Klik kanan -> Potong.
  8. Klik kanan -> Salin.
  9. Menyeret dan melepas teks dari aplikasi lain.
  10. Memodifikasi dengan Javascript.
  11. Memodifikasi dengan alat debug, seperti Firebug.

Saya ingin menampilkannya menggunakan console.log. Apakah ini mungkin di Javascript / jQuery, dan jika demikian, bagaimana cara melakukannya?


Pertanyaan Anda seperti ini menarik, tetapi Anda mengatakan dalam komentar bahwa "Apa yang saya cari lebih merupakan daftar dari semua peristiwa yang dipecat sehingga saya tahu mana yang tersedia untuk saya ikuti" - mengapa Anda tidak tanyakan itu? Doco MSDN cukup bagus untuk ini: msdn.microsoft.com/en-us/library/ms533051(v=VS.85).aspx - tidak semua peristiwa yang terdaftar didukung di semua browser, tetapi jika Anda memeriksa dokumen untuk acara 'on_xyz_' itu akan memberi tahu Anda "Acara ini ditentukan dalam HTML 4.0.", atau "Tidak ada standar publik yang berlaku untuk acara ini", atau apa pun.
nnnnnn

Jawaban:


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

Itu akan memberi Anda banyak (tetapi tidak semua) informasi tentang jika suatu peristiwa dipecat ... selain mengkodekannya secara manual seperti ini, saya tidak dapat memikirkan cara lain untuk melakukan itu.


Aneh bagaimana Anda dan Shawn salah eja function, dan dengan cara yang sama :).
Daniel T.

1
Sepertinya metode ini akan mengikat semua kejadian asli. Saya menduga tidak ada cara untuk menampilkan acara khusus, misalnya jika sebuah plugin mengaktifkan beberapa acara khusus?
Daniel T.

2
Saya menerima ini sebagai jawaban, tetapi jawaban sebenarnya untuk pertanyaan saya adalah "ya dan tidak". Apa yang saya cari lebih merupakan daftar dari semua peristiwa yang dipecat sehingga saya tahu mana yang tersedia untuk saya ikuti. Dalam hal ini, saya dapat melihat kapan peristiwa tersebut dipecat, tetapi saya harus mengetahui namanya sebelumnya.
Daniel T.

3
@ Joseph: mengenai komentar Anda sebelumnya "fokus bukanlah peristiwa asli" - um ... ya, sudah ada sejak lama sebelum jQuery (dan sebelum Chrome dan FF, dalam hal ini). Selain itu, Anda mungkin ingin menambahkan blurke daftar acara Anda.
nnnnnn

3
monitorEvents (dokumen) adalah jawaban sebenarnya
neaumusic

206

Saya tidak tahu mengapa tidak ada yang menggunakan ini ... (mungkin karena ini hanya masalah webkit)

Buka 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
Ini tidak mencakup acara khusus tetapi sangat membantu memahami tumpukan acara.
sidonaldson

Ini jawaban yang benar. Anda tidak ingin menggunakan console.log dalam kode produksi, tidak masalah menggunakan konsol untuk acara debug
neaumusic

1
Googleing monitorEventstidak memberikan informasi yang relevan tentang ini, juga, saya sangat curiga ini sangat tidak standar
vsync

3
@vsync coba "monitorEvents" dengan tanda kutip. Itu bagian dari objek konsol tetapi bergantung pada browser. Ini hanya alat debugging karena bergantung pada konsol ... jadi standar tidak relevan
sidonaldson

2
Perhatikan bahwa Anda juga dapat menggunakan sesuatu seperti monitorEvents($0, 'mouse');untuk mencatat semua kejadian dari elemen yang diinspeksi (Klik kanan> "Inspect"). ( Briangrinstead.com/blog/chrome-developer-tools-monitorevents )
rinogo

32

Ada cara umum yang bagus menggunakan koleksi .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);
});

Ini mencatat setiap peristiwa yang telah terikat ke elemen oleh jQuery saat peristiwa spesifik ini diaktifkan. Kode ini sangat membantu saya berkali-kali.

Btw: Jika Anda ingin melihat setiap kemungkinan peristiwa yang ditembakkan pada suatu objek gunakan firebug: cukup klik kanan pada elemen DOM di tab html dan centang "Peristiwa Log". Setiap acara kemudian akan dicatat ke konsol (ini terkadang sedikit mengganggu karena mencatat setiap gerakan mouse ...).


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
Jawaban terlengkap
leymannx

12

Saya tahu jawabannya telah diterima untuk ini, tetapi saya pikir mungkin ada cara yang sedikit lebih dapat diandalkan di mana Anda tidak perlu mengetahui nama acaranya terlebih dahulu. Ini hanya berfungsi untuk acara asli meskipun sejauh yang saya tahu, bukan acara khusus yang telah dibuat oleh plugin. Saya memilih untuk menghilangkan penggunaan jQuery untuk sedikit menyederhanakan banyak hal.

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

Saya harap ini membantu siapa saja yang membaca ini.

EDIT

Jadi saya melihat pertanyaan lain di sini yang serupa, jadi saran lain adalah melakukan hal berikut:

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

Ini adalah solusi paling elegan dari kelompok itu. Saya kira tidak mungkin untuk menemukan acara khusus karena itu bisa dikeluarkan melalui dispatchEvent (). Namun, ini mencakup semua yang lain dalam sedikit kode yang ringkas, bebas ketergantungan,.
Roberto

10

Benang tua, saya tahu. Saya juga membutuhkan sesuatu untuk memantau acara dan menulis solusi yang sangat berguna (luar biasa) ini. Anda dapat memantau semua kejadian dengan hook ini (dalam pemrograman windows ini disebut hook). Pengait ini tidak mempengaruhi pengoperasian perangkat lunak / program Anda.

Di log konsol, Anda dapat melihat sesuatu seperti ini:

log konsol

Penjelasan tentang apa yang Anda lihat:

Di log konsol, Anda akan melihat semua acara yang Anda pilih (lihat di bawah "cara menggunakan" ) dan menunjukkan tipe objek, nama kelas, id, <: nama fungsi>, <: nama peristiwa>. Pemformatan objek seperti css.

Saat Anda mengklik tombol atau event terikat apa pun, Anda akan melihatnya di log konsol.

Kode yang saya tulis:

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

Contoh cara menggunakannya:

Pantau semua acara:

setJQueryEventHandlersDebugHooks();

Pantau semua pemicu saja:

setJQueryEventHandlersDebugHooks(true,false,false);

Pantau semua acara ON saja:

setJQueryEventHandlersDebugHooks(false,true,false);

Pantau semua OFF hanya melepas ikatan:

setJQueryEventHandlersDebugHooks(false,false,true);

Keterangan / Pemberitahuan:

  • Gunakan ini hanya untuk debugging, matikan saat menggunakan dalam versi final produk
  • Jika Anda ingin melihat semua event, Anda harus memanggil fungsi ini langsung setelah jQuery dimuat
  • Jika Anda hanya ingin melihat lebih sedikit acara, Anda dapat memanggil fungsi tersebut pada saat Anda membutuhkannya
  • Jika Anda ingin menjalankannya secara otomatis, place () (); di sekitar fungsi

Semoga membantu! ;-)


Hai @AmirFo, terima kasih sudah mencoba. Karena Anda tidak memberikan contoh apa pun yang telah Anda lakukan, tidak mungkin untuk melihat apakah masalahnya ada di kode Anda atau milik saya. Karena ada orang lain yang berhasil menggunakan contoh ini, ada kemungkinan Anda melakukan kesalahan. Sudahkah Anda memeriksa kode Anda untuk kesalahan?
Codebeat

Tidak ada kesalahan. Saya memicu beberapa peristiwa, Tapi tidak ada log yang muncul di konsol! Saya menggunakan versi chrome terbaru di ubuntu, linux.
Amir Fo

@AmirFo: Apakah Anda juga mencobanya di Firefox? Versi jQuery apa?
Codebeat

@AmirFo: Bagaimana Anda memicu peristiwa tersebut? Apakah Anda mengikat peristiwa apa pun ke elemen DOM sebelum memicunya?
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
Dapatkah Anda memberikan lebih banyak informasi tentang cara kerjanya dan apa tepatnya fungsinya? Bagaimana saya bisa melampirkannya ke elemen?
Josiah

Skrip ini memodifikasi HTMLElement.prototype.addEventListenerdan mungkin tidak boleh digunakan dalam produksi, tetapi itu sudah sangat membantu saya untuk tujuan debugging.
Günter Zöchbauer

1
Ini tidak bekerja dengan 1 elemen, ini bekerja untuk SEMUA DARI MEREKA. Ini mengetuk penangan kejadian jendela dan mendengarkan semua yang terjadi. Ia bekerja dengan penangan kejadian asli, dan jQuery.
Robert Plummer

2

Cukup tambahkan ini ke halaman dan tidak ada kekhawatiran lain, akan menangani istirahat untuk Anda:

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

Anda juga dapat menggunakan console.log ('Input event:' + e.type) untuk membuatnya lebih mudah.


3
Aneh bagaimana Anda dan Joseph salah mengeja function, dan dengan cara yang sama :).
Daniel T.

lol, hei ... dia sudah menulis beberapa dan saya mengalami peningkatan. ;)
Shawn Khameneh

1
Jangan biarkan saya mengomentari jawaban lain, Anda dapat menggunakan .data ("peristiwa") untuk mengambil daftar acara.
Shawn Khameneh

Bagaimana cara kerjanya? Saya mencoba $('input').data('events')dan hasilnya tidak ditentukan.
Daniel T.

Itu akan mengembalikan peristiwa terikat saat ini, yang mencakup peristiwa khusus. Jika tidak ada acara yang terikat, itu akan mengembalikan tidak ditentukan.
Shawn Khameneh

1

LANGKAH 1: Periksa eventsuntuk HTML elementdi developer console:

masukkan deskripsi gambar di sini

LANGKAH 2: Dengarkan yang eventsingin kami tangkap:

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

Semoga berhasil...


1

Saya baru-baru ini menemukan dan memodifikasi potongan ini dari posting SO yang sudah ada yang tidak dapat saya temukan lagi tetapi menurut saya sangat berguna

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

Ini menggunakan sedikit ES6 untuk kecantikan, tetapi dapat dengan mudah diterjemahkan untuk browser lama juga. Dalam fungsi yang dilampirkan ke event listener, saat ini hanya keluar dari event apa yang terjadi tetapi di sinilah Anda dapat mencetak informasi tambahan, atau menggunakan switch case e.type, Anda hanya dapat mencetak informasi pada event tertentu.


0

Berikut adalah cara non-jquery untuk memantau peristiwa di konsol dengan kode Anda dan tanpa menggunakan monitorEvents () karena itu hanya berfungsi di Konsol Pengembang Chrome. Anda juga dapat memilih untuk tidak memantau kejadian tertentu dengan mengedit larik 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.