Bagaimana menemukan pendengar acara pada simpul DOM saat debugging atau dari kode JavaScript?

Saya memiliki halaman di mana beberapa pendengar acara dilampirkan ke bidang input dan pilih persegi panjang. Apakah ada cara untuk mengetahui pendengar acara mana yang memonitor node DOM tertentu dan untuk acara apa?

Acara terhubung menggunakan:

  • Prototipe Event.observe ;
  • addEventListener DOM;
  • Sebagai atribut dari element.onclick .
706
15 янв. Navneet diatur 15 Jan 2009-01-15 17:19 '09 pada 17:19 2009-01-15 17:19
@ 17 balasan

Jika Anda hanya perlu memeriksa apa yang terjadi pada halaman, Anda dapat mencoba bookmarklet Peristiwa Visual .

Refresh : Visual Event 2 ,

469
06 авг. balasan diberikan kepada Andrew Hedges 06 Agustus 2010-08-06 20:48 '10 pada pukul 8:48 PM 2010-08-06 20:48

Itu tergantung pada bagaimana peristiwa terkait. Sebagai ilustrasi, misalkan kita memiliki penangan klik berikut:

 var handler = function() { alert('clicked!') }; 

Kami akan melampirkannya ke elemen kami menggunakan metode yang berbeda, beberapa di antaranya memungkinkan kami untuk menguji dan beberapa tidak.

Metode A) Penangan Kejadian Tunggal

 element.onclick = handler; // inspect alert(element.onclick); // alerts "function() { alert('clicked!') }" 

Metode B) beberapa penangan acara

 if(element.addEventListener) { // DOM standard element.addEventListener('click', handler, false) } else if(element.attachEvent) { // IE element.attachEvent('onclick', handler) } // cannot inspect element to find handlers 

Metode C): jQuery

 $(element).click(handler); 
  • 1.3.x

     // inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, value) { alert(value) // alerts "function() { alert('clicked!') }" }) 
  • 1.4.x (menyimpan pawang di dalam objek)

     // inspect var clickEvents = $(element).data("events").click; jQuery.each(clickEvents, function(key, handlerObj) { alert(handlerObj.handler) // alerts "function() { alert('clicked!') }" // also available: handlerObj.type, handlerObj.namespace }) 

(lihat jQuery.fn.data dan jQuery.data )

Metode D): Prototipe (kotor)

 $(element).observe('click', handler); 
  • 1.5.x

     // inspect Event.observers.each(function(item) { if(item[0] == element) { alert(item[2]) // alerts "function() { alert('clicked!') }" } }) 
  • mulai dari 1.6 hingga 1.6.0.3 inklusif (sangat sulit di sini)

     // inspect. "_eventId" is for < 1.6.0.3 while // "_prototypeEventID" was introduced in 1.6.0.3 var clickEvents = Event.cache[element._eventId || (element._prototypeEventID || [])[0]].click; clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" }) 
  • 1.6.1 (sedikit lebih baik)

     // inspect var clickEvents = element.getStorage().get('prototype_event_registry').get('click'); clickEvents.each(function(wrapper){ alert(wrapper.handler) // alerts "function() { alert('clicked!') }" }) 
346
15 янв. jawabannya diberikan Crescent Fresh 15 Januari. 2009-01-15 18:13 '09 pada 18:13 2009-01-15 18:13

getEventListeners(domElement) Chrome, Firefox, Vivaldi dan Safari getEventListeners(domElement) di konsol pengembang.

Untuk sebagian besar keperluan debugging, ini dapat digunakan.

Di bawah ini adalah rekomendasi yang sangat bagus: https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

203
14 мая '13 в 16:40 2013-05-14 16:40 jawabannya diberikan oleh Raghav pada 14 Mei '13 pukul 4:40 2013-05-14 16:40

Inspektur WebKit di browser Chrome atau Safari sekarang melakukan ini. Ini menampilkan pendengar acara untuk elemen DOM ketika Anda memilihnya di panel Elemen.

81
17 янв. jawabannya diberikan Ishan 17 Januari. 2011-01-17 10:39 '11 pada 10:39 2011-01-17 10:39

Dalam JavaScript, Anda dapat membuat daftar semua pendengar acara : tidak terlalu sulit; Anda hanya perlu meretas metode prototype elemen HTML (sebelum menambahkan pendengar).

 function reportIn(e){ var a = this.lastListenerInfo[this.lastListenerInfo.length-1]; console.log(a) } HTMLAnchorElement.prototype.realAddEventListener = HTMLAnchorElement.prototype.addEventListener; HTMLAnchorElement.prototype.addEventListener = function(a,b,c){ this.realAddEventListener(a,reportIn,c); this.realAddEventListener(a,b,c); if(!this.lastListenerInfo){ this.lastListenerInfo = new Array()}; this.lastListenerInfo.push({a : a, b : b , c : c}); }; 

Sekarang setiap elemen yang mengikat ( a ) akan memiliki properti lastListenerInfo berisi semua pendengarnya. Dan itu bahkan berfungsi untuk menghi>

61
22 июня '11 в 7:32 2011-06-22 07:32 jawabannya diberikan oleh Ivan Castellanos pada 22 Juni '11 pada 7:32 2011-06-22 07:32

(Menulis u>pertanyaan ini , karena itu penting di sini.)

Saat debugging, jika Anda hanya ingin melihat acara, saya sarankan ...

  • Acara visual
  • Bagian "Elemen" pada alat pengembang Chrome: pilih item dan temukan "Pendengar Acara" di sudut kanan bawah (sama di Firefox).

Jika Anda ingin menggunakan acara dalam kode Anda dan menggunakan jQuery hingga versi 1.8, Anda dapat menggunakan:

 $(selector).data("events") 

untuk mendapatkan acara. Dimulai dengan versi 1.8, penggunaan .data ("events") dihentikan (lihat kode kesalahan besar ini ). Anda bisa menggunakan:

 $._data(element, "events") 

Contoh lain: tulis semua acara klik pada tautan spesifik ke konsol:

 var $myLink = $('a.myClass'); console.log($._data($myLink[0], "events").click); 

(lihat http://jsfiddle.net/HmsQC/ untuk contoh kerja)

Sayangnya, menggunakan data $ ._ tidak disarankan , kecuali untuk debugging, karena ini adalah struktur jQuery internal dan dapat diubah dalam rilis mendatang. Sayangnya, saya tidak tahu cara sederhana lainnya untuk mengakses acara.

38
22 окт. Luke diposting pada 22 Oktober 2012-10-22 22:04 '12 pada jam 10:04 2012-10-22 22:04

Gunakan getEventListeners di Google Chrome :

 getEventListeners(document.getElementByID('btnlogin')); getEventListeners($('#btnlogin')); 
26
19 марта '14 в 12:30 2014-03-19 12:30 jawabannya diberikan oleh Pranay Soni pada 19 Maret '14 pukul 12:30 2014-03-19 12:30

1: Prototype.observe menggunakan Element.addEventListener (lihat kode sumber )

2: Anda dapat mengganti Element.addEventListener untuk mengingat pendengar yang ditambahkan (properti EventListenerList nyaman telah dihapus dari proposal spesifikasi DOM3). Jalankan kode ini sebelum melampirkan acara apa pun:

 (function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; this.eventListenerList[a].push(b); }; })(); 

Baca semua acara:

 var clicks = someElement.eventListenerList.click; if(clicks) clicks.forEach(function(f) { alert("I listen to this function: "+f.toString()); }); 

Dan jangan lupa untuk mengganti Element.removeEventListener untuk menghapus acara dari Element.eventListenerList kustom.

3: Properti Element.onclick membutuhkan perhatian khusus:

 if(someElement.onclick) alert("I also listen tho this: "+someElement.onclick.toString()); 

4: jangan lupa atribut Element.onclick konten: ini adalah dua hal yang berbeda:

 someElement.onclick = someHandler; // IDL attribute someElement.setAttribute("onclick","otherHandler(event)"); // content attribute 

Jadi, Anda juga perlu memproses:

 var click = someElement.getAttribute("onclick"); if(click) alert("I even listen to this: "+click); 

Label buklet Acara Visual (disebutkan dalam jawaban paling populer) hanya mencuri cache penangan perpustakaan pengguna:

Ternyata tidak ada metode standar yang disediakan oleh antarmuka DOM yang direkomendasikan W3C untuk mengetahui pendengar acara mana yang dilampirkan ke elemen tertentu. Meskipun kelihatannya seperti pengawasan, ada saran untuk menyertakan properti yang disebut eventListenerList sebelum spesifikasi DOM Level 3, tetapi sayangnya dihapus dalam konsep berikutnya. Oleh karena itu, kita dipaksa untuk melihat pustaka Javascript terpisah yang biasanya dikelola oleh cache dari peristiwa yang terhubung (sehingga mereka dapat dihapus kemudian dan abstraksi berguna lainnya dapat dilakukan).

Jadi, agar Acara Visual untuk menampilkan acara, itu harus dapat menganalisis informasi acara dari perpustakaan Javascript.

Elemen-elemen utama dapat dipertanyakan (mis. Karena ada beberapa fungsi khusus DOM, seperti koleksi >

22
03 апр. Membalas Jan Turoň Apr 03 2014-04-03 18:08 '14 pada 18:08 2014-04-03 18:08

Anda dapat membungkus metode DOM Anda sendiri untuk mengontrol pendengar acara dengan meletakkannya di bagian atas <head> :

 <script> (function(w){ var originalAdd = w.addEventListener; w.addEventListener = function(){ // add your own stuff here to debug return originalAdd.apply(this, arguments); }; var originalRemove = w.removeEventListener; w.removeEventListener = function(){ // add your own stuff here to debug return originalRemove.apply(this, arguments); }; })(window); </script> 

H / T @ les2

21
06 нояб. Jawaban diberikan oleh Jon z 06 Nov 2015-11-06 20:49 15 di 20:49 2015-11-06 20:49

Sekarang alat pengembang Firefox melakukannya. Acara ditampilkan dengan menekan tombol "ev" di sebelah kanan setiap tampilan item, termasuk acara jQuery dan DOM .

2019

16
14 янв. Jawabannya diberikan oleh simonzack 14 januari . 2015-01-14 18:33 '15 pada 18:33 2015-01-14 18:33

Jika Anda memiliki Firebug , Anda dapat menggunakan console.dir(object or array) untuk mencetak pohon yang indah di log konsol dari setiap pemindai JavaScript, array atau objek.

Coba:

 console.dir(clickEvents); 

atau

 console.dir(window); 
12
08 янв. Balas Michael Butler 08 Jan 2010-01-08 01:52 '10 pada 1:52 2010-01-08 01:52

Opera 12 (bukan mesin Chrome Webkit terakhir) Dragonfly memiliki ini untuk sementara waktu dan ditampilkan dengan jelas dalam struktur DOM Menurut saya, ini adalah debugger yang sangat baik, dan ini adalah satu-satunya alasan saya masih menggunakan versi berdasarkan Opera 12 (tidak ada versi v13, V14 dan v15 berbasis webkit hi>

2019

7
28 нояб. Jawaban diberikan kepada Daniel Sokolowski 28 November 2013-11-28 19:30 '13 pukul 19:30 2013-11-28 19:30

Solusi yang sepenuhnya berfungsi berdasarkan respons Jan Turon - berperilaku seperti getEventListeners() dari konsol:

(Ada kesalahan kecil dengan duplikat. Dalam kasus apa pun, ini tidak banyak berarti.)

 (function() { Element.prototype._addEventListener = Element.prototype.addEventListener; Element.prototype.addEventListener = function(a,b,c) { if(c==undefined) c=false; this._addEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; //this.removeEventListener(a,b,c); // TODO - handle duplicates.. this.eventListenerList[a].push({listener:b,useCapture:c}); }; Element.prototype.getEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined) return this.eventListenerList; return this.eventListenerList[a]; }; Element.prototype.clearEventListeners = function(a){ if(!this.eventListenerList) this.eventListenerList = {}; if(a==undefined){ for(var x in (this.getEventListeners())) this.clearEventListeners(x); return; } var el = this.getEventListeners(a); if(el==undefined) return; for(var i = el.length - 1; i >= 0; --i) { var ev = el[i]; this.removeEventListener(a, ev.listener, ev.useCapture); } }; Element.prototype._removeEventListener = Element.prototype.removeEventListener; Element.prototype.removeEventListener = function(a,b,c) { if(c==undefined) c=false; this._removeEventListener(a,b,c); if(!this.eventListenerList) this.eventListenerList = {}; if(!this.eventListenerList[a]) this.eventListenerList[a] = []; // Find the event in the list for(var i=0;i<this.eventListenerList[a].length;i++){ if(this.eventListenerList[a][i].listener==b, this.eventListenerList[a][i].useCapture==c){ // Hmm.. this.eventListenerList[a].splice(i, 1); break; } } if(this.eventListenerList[a].length==0) delete this.eventListenerList[a]; }; })(); 

Gunakan:

someElement.getEventListeners([name]) - mengembalikan daftar pendengar acara, jika namanya disetel, mengembalikan array pendengar untuk acara ini.

someElement.clearEventListeners([name]) - hapus semua pendengar acara, jika nama diatur, hapus hanya pendengar untuk acara ini

6
27 июня '15 в 13:47 2015-06-27 13:47 jawabannya diberikan n00b 27 Juni '15 pada 13:47 2015-06-27 13:47

Prototipe 1.7.1.

 function get_element_registry(element) { var cache = Event.cache; if(element === window) return 0; if(typeof element._prototypeUID === 'undefined') { element._prototypeUID = Element.Storage.UID++; } var uid = element._prototypeUID; if(!cache[uid]) cache[uid] = {element: element}; return cache[uid]; } 
4
17 янв. Balas diberikan oleh Ronald Lewis Berner II 17 Jan. 2013-01-17 20:28 '13 pada 20:28 2013-01-17 20:28

Saya mencoba melakukan ini di jQuery 2.1, dan menggunakan metode " $().click() -> $(element).data("events").click; " tidak bekerja.

Saya menyadari bahwa dalam kasus saya hanya $ ._ data () berfungsi:

 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body> </body> 
2
19 мая '15 в 11:33 2015-05-19 11:33 Jawaban diberikan oleh Joel Barba 19 Mei '15 pukul 11:33 2015-05-19 11:33
28 февр. Balas oleh T.Todua pada 28 Feb 2017-02-28 18:13 '17 pada 18:13 2017-02-28 18:13

Saya baru-baru ini bekerja dengan acara dan ingin melihat / mengontrol semua acara di halaman. Setelah mempertimbangkan solusi yang memungkinkan, saya memutuskan untuk menempuh jalan saya sendiri dan membuat sistem pemantauan acara saya sendiri. Jadi, saya melakukan tiga hal.

Pertama, saya membutuhkan wadah untuk semua pendengar acara di halaman: objek EventListeners . Ini memiliki tiga metode yang berguna: add() , remove() dan get() .

Kemudian saya membuat objek EventListener untuk menyimpan informasi yang diperlukan untuk acara tersebut, yaitu: target , type , callback , options , useCapture , wantsUntrusted dan menambahkan metode remove() untuk menghapus listener.

Akhirnya, saya memperpanjang addEventListener() saya sendiri dan removeEventListener() untuk membuatnya berfungsi dengan objek EventListener dibuat ( EventListener dan EventListeners ).

Aplikasi:

 var bodyClickEvent = document.body.addEventListener("click", function () { console.log("body click"); }); // bodyClickEvent.remove(); 

addEventListener() membuat objek EventListener , menambahkannya ke EventListeners dan mengembalikan objek EventListener , sehingga Anda bisa menghapusnya nanti.

EventListeners.get() dapat digunakan untuk melihat pendengar pada halaman. Ini menerima EventTarget atau string (tipe acara).

 // EventListeners.get(document.body); // EventListeners.get("click"); 

demonstrasi

Katakanlah kita ingin mengetahui setiap pendengar acara di halaman ini. Kami dapat melakukan ini (dengan asumsi bahwa Anda menggunakan ekstensi pengelola skrip, Tampermonkey dalam kasus ini). Script berikut melakukan hal berikut:

 // ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @include https://stackoverflow.com/* // @grant none // ==/UserScript== (function() { fetch("https://raw.githubusercontent.com/akinuri/js-lib/master/EventListener.js") .then(function (response) { return response.text(); }) .then(function (text) { eval(text); window.EventListeners = EventListeners; }); })(window); 

Dan ketika kami daftar semua pendengar, dikatakan ada 299 pendengar acara. Tampaknya ada beberapa duplikat, tetapi saya tidak tahu apakah itu benar-benar duplikat. Tidak setiap jenis acara digandakan, sehingga semua "duplikat" ini bisa menjadi pendengar individu.

2019

Pertanyaan lain tentang tag atau Ajukan pertanyaan