Hata ayıklama ya da JavaScript kodundan DOM düğümünde olay dinleyicilerini nasıl bulabilirim?

Bəzi hadisə dinləyicilərinin giriş sahələrinə yerləşdiyi və düzbucaqlıları seçən bir səhifə var. Hansı hadisə dinləyicilərinin müəyyən bir DOM nodu izləyib və hansı hadisə ilə bağlı olduğunu tapmaq üçün bir yol varmı?

Hadisələr aşağıdakılardan istifadə olunur:

  • Prototip Event.observe ;
  • DOM addEventListener ;
  • element.onclick bir atributu kimi.
706
15 янв. Navneet 15 yanvarda təyin olundu 2009-01-15 17:19 '09 at 17:19 'da 2009-01-15 17:19
@ 17 cavab

Yalnız səhifənizdə nə baş verdiyini yoxlamağınız lazımdırsa, Visual Event bookmarklet'i sınayabilirsiniz.

Yeniləmə : Visual Event 2 ,

469
06 авг. Andrew Hedges'e 06 Avqust cevap verildi 2010-08-06 20:48 '10 at 8:48 PM 2010-08-06 20:48

Bu, hadisələrin necə əlaqəli olduğuna bağlıdır. Şəkil üçün, aşağıdakı klik işləyicisi olduğumuzu güman et:

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

Biz onu müxtəlif üsullardan istifadə edərək elementimizə əlavə edəcəyik, bəziləri isə test etməyə imkan verir, bəziləri isə yox.

Yöntem A) Tekli Event Handler

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

B) çoxlu hadisə işləyiciləri

 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 
border=0

Metod 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 (işəgötürənin obyektin içərisində saxlanılması)

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

(bax jQuery.fn.datajQuery.data )

D metodu: Prototip (çirkli)

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

     // inspect Event.observers.each(function(item) { if(item[0] == element) { alert(item[2]) // alerts "function() { alert('clicked!') }" } }) 
  • 1.6'dan 1.6.0.3'e qədər (burada çox çətin)

     // 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 (bir qədər yaxşı)

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

Geliştirici konsolunda Chrome, Firefox, Vivaldi və Safari getEventListeners(domElement) .

Çoğu hata ayıklama amacıyla bu istifadə edilə bilər.

Aşağıda çox yaxşı bir tövsiyədir: https://developers.google.com/chrome-developer-tools/docs/commandline-api#geteventlistenersobject

203
14 мая '13 в 16:40 2013-05-14 16:40 Cavab Raghav tərəfindən 14 May '13, 4:40 'də verilir 2013-05-14 16:40

Chrome və ya Safari brauzerlərindəki WebKit Müfəttişi bunu indi edir. Element panelində seçdiyiniz zaman DOM elemanı üçün hadisə dinləyicilərini göstərir.

81
17 янв. cavab 17 İyun işana verilir . 2011-01-17 10:39 '11 at 10:39 2011-01-17 10:39

JavaScript-də, bütün hadisə dinləyicilərini qeyd edə bilərsiniz : bu çətin deyil; yalnız HTML elementlərinin prototype metodunu (dinləyicilər əlavə etməzdən əvvəl) silmək lazımdır.

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

İndi hər bir bağlama elementi ( a ) bütün dinləyicilərini ehtiva edən bir lastListenerInfo xüsusiyyətinə sahib olacaq. Və hətta dinləyiciləri anonim funksiyaları ilə aradan qaldırmaq üçün çalışır.

61
22 июня '11 в 7:32 2011-06-22 07:32 Cavab İvan Castellanos tərəfindən 22 İyun 'da 7:32' də verildi. 2011-06-22 07:32

(Cavabın bu sualdan yenidən yazılması, burada vacibdir.)

Hata ayıklama zamanı, yalnız hadisələri görmək istəyirsinizsə, ya da ...

  • Görkəmli hadisə
  • Chrome inkişaf etdirici vasitələrinin "Elements" bölməsi: bir maddə seçin və aşağı sağ küncdə (Firefox'a bənzər) "Hadisə dinləyicilərini" tapın.

Kodunuzdakı hadisələri istifadə etmək və 1.8-ə qədər jQuery istifadə etmək istəyirsinizsə, istifadə edə bilərsiniz:

 $(selector).data("events") 

hadisələr əldə etmək. Sürüm 1.8'den başlayaraq, .data ("hadisələr") istifadə dayandırılmışdır ( bu böyük səhv koduna baxın). Siz istifadə edə bilərsiniz:

 $._data(element, "events") 

Başqa bir nümunə: Bütün klik hadisələrini konsolun xüsusi bir linkinə yazın:

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

(iş nümunəsi üçün http://jsfiddle.net/HmsQC/ səhifəsinə baxın)

Təəssüf ki, daxili bir jQuery quruluşu olduğundan və gələcək relizlər ilə dəyişdirilə bilər, çünki, $ ._ məlumatlarını istifadə edərək , diskussiya istisna olmaqla, tövsiyə edilmir . Təəssüf ki, hadisələrə daxil olmaq üçün digər sadə yolları bilmirəm.

38
22 окт. Luke 22 oktyabrda nəşr olundu 2012-10-22 22:04 '12 at 10:04 pm 2012-10-22 22:04

Google Chrome-da getEventListeners istifadə edin:

 getEventListeners(document.getElementByID('btnlogin')); getEventListeners($('#btnlogin')); 
26
19 марта '14 в 12:30 2014-03-19 12:30 Cavab Pranay Soni tərəfindən 19 Mart '14 'də saat 12.30' da veriləcək 2014-03-19 12:30

1: Prototype.observe Element.addEventListener istifadə edir (bax mənbə kodu )

2: Əlavə dinləyiciləri xatırlamaq üçün Element.addEventListener ləğv edə bilərsiniz (rahat EventListenerList xüsusiyyət DOM3 spesifikasiyası təklifindən çıxarılmışdır). Hər hansı bir hadisə əlavə etmədən əvvəl bu kodu işləyin:

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

Bütün hadisələri oxuyun:

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

Element.removeEventListener dən hadisəni aradan qaldırmaq üçün Element.removeEventListener yalnış unutmayın.

3: Element.onclick əmlakı xüsusi diqqət tələb edir:

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

4: content Element.onclick xüsusiyyətini Element.onclick : bunlar iki fərqli şeydir:

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

Beləliklə, siz də işləməlisiniz:

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

Visual Event kitabçası-etiket (ən məşhur cavabda göstərilən) yalnız istifadəçi kitabxanasının işlənicisinin önbelleğini oğurlayır:

Hansı hadisənin dinləyicilərinin müəyyən bir elementə yerləşdirildiyini öyrənmək üçün W3C tərəfindən təklif olunan DOM interfeysi tərəfindən təqdim edilən standart metod yoxdur. Nəzarət kimi görünə bilər, baxmayaraq ki, DOM spesifikasiyası Səviyyə 3-dən əvvəl eventListenerList adlı bir əmlakı daxil etmək üçün bir təklif var idi, lakin təəssüf ki, sonrakı layihələrdə çıxarıldı. Buna görə də, biz bağlı olan hadisələrin önbelleği tərəfindən qorunan ayrı Javascript kitabxanalarına baxmaq məcburiyyətində qalırıq (daha sonra silinəcək və digər faydalı abstractions tətbiq edilə bilər).

Beləliklə, Visual Event-in hadisələri göstərməsi üçün, hadisə məlumatlarını Javascript kitabxanasından analiz edə bilməli olmalıdır.

Üstün elementlər sorgulanabilir (məsələn, JS-də kodlaşdırılamayan canlı koleksiyonlar kimi bəzi DOM xüsusi funksiyaları var), ancaq ilk olaraq eventListenerList dəstəyi təmin edir və Chrome, Firefox və Opera ( IE7-də işləməyin).

22
03 апр. Jan Turon'a aprelin 03-də cavab verin 2014-04-03 18:08 '14 at 18:08 2014-04-03 18:08

<head> üstünə qoyaraq hadisə dinləyicilərini nəzarət etmək üçün öz DOM metodlarını saxlaya bilərsiniz:

 <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 нояб. Cavab Jon z Nov 06 tərəfindən verilir 2015-11-06 20:49 '15 at 8:49 PM 2015-11-06 20:49

İndi Firefox geliştirici alətləri bunu edir. Hadisələr jQueryDOM hadisələri, o cümlədən hər bir maddə ekranının sağ tərəfindəki "ev" düyməsini basaraq göstərilir.

2019

16
14 янв. cavab simonzack tərəfindən verilir 14 yanvar. 2015-01-14 18:33 '15 at 18:33 2015-01-14 18:33

Firebug varsa, hər hansı bir JavaScript skanerinin, dizisinin və ya obyektinin konsol jurnalında gözəl bir ağac çap etmək üçün console.dir(object or array) istifadə edə bilərsiniz.

Keçir:

 console.dir(clickEvents); 

və ya

 console.dir(window); 
12
08 янв. Cavab Michael Batler Jan 08 2010-01-08 01:52 '10 at 1:52 2010-01-08 01:52

Opera 12 (son Chrome Webkit mühərriki deyil) Dragonfly bu bir müddətdir və DOM strukturunda açıq şəkildə nümayiş olunur, mənim fikrimcə, bu, yaxşı bir hata ayıklayıcısıdır və bu hələ Opera 12-də (versiya v13, Webkit-based v14 və v15 itkin Dragonfly)

2019

7
28 нояб. Cavab Daniel Sokolowski noyabrın 28-də verilir 2013-11-28 19:30 '13 saat 19:30 'da 2013-11-28 19:30

Jan Turon cavabına əsaslanan tamamilə işləyən həll - konsoldan getEventListeners() kimi davranır:

(Çoğaltılan kiçik bir səhv var. Hər halda, bu çox pozulmur.)

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

İstifadə edin:

someElement.getEventListeners([name]) - hadisə dinləyicilərinin siyahısını qaytarır, əgər adı müəyyənləşsə, bu hadisə üçün dinləyicilərin bir sıra qaytarır.

someElement.clearEventListeners([name]) - adı müəyyən edildikdə bütün hadisə dinləyicilərini silin, yalnız bu hadisə üçün dinləyiciləri çıxarın

6
27 июня '15 в 13:47 2015-06-27 13:47 Cavab verilir n00b 27 iyun, '15 at 13:47 2015-06-27 13:47

Prototip 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 янв. Ronald Lewis Berner II tərəfindən verilmiş cavab 17 Yanvar. 2013-01-17 20:28 '13 saat 20:28 2013-01-17 20:28

Bunu jQuery 2.1 ilə etməyə çalışıram və " $().click() -> $(element).data("events").click; üsulunu istifadə edərək." $().click() -> $(element).data("events").click; "İşə yaramır.

Mən başa düşdüm ki, mənim vəziyyətimdə yalnız $ ._ data () funksiyaları işləyir:

 <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 Cavab Joel Barba tərəfindən 19 May '15 'də saat 11:33' də verilir. 2015-05-19 11:33
28 февр. T.Todua tərəfindən 28 Fevralda cavab verin 2017-02-28 18:13 '17 də 18:13 2017-02-28 18:13

Bu yaxınlarda hadisələrlə işləyirdim və bütün hadisələri səhifədə görmək və nəzarət etmək istədim. Mümkün çözümləri nəzərdən keçirdikdən sonra, mən öz yolumla getmək qərarına gəldim və öz tədbirin monitorinq sistemini yaratdım. Beləliklə, mən üç şey etdim.

Birincisi, səhifədəki bütün hadisə dinləyicilərinə bir konteynerə ehtiyacım var: EventListeners obyekti. Üç faydalı üsul vardır: add() , remove()get() .

Sonra EventListener obyekti üçün lazımi informasiyanı, yəni target , type , callback , options , useCapture , wantsUntrusted vermək və dinləyiciyi çıxarmaq üçün remove remove() metodu əlavə etmək üçün yaradılmışdır.

Nəhayət, öz addEventListener()removeEventListener() , onları EventListener obyektləri ( EventListenerEventListeners ) ilə işləmək üçün genişləndirdim.

Ərizə:

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

addEventListener() bir EventListener obyektini yaradır, onu EventListeners əlavə edir və bir EventListener obyektini qaytarır, belə ki, daha sonra aradan qaldırıla bilərsiniz.

EventListeners.get() bir səhifədə dinləyicilərə baxmaq üçün istifadə edilə bilər. Bir EventTarget və ya simli (hadisə növü) qəbul edir.

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

nümayiş

Deyək, bu cari səhifənin hər bir hadisə dinləyicisini bilmək istəyirik. Bunu edə bilərik (ssenari müdirinin uzadılması, bu halda Tampermonkey istifadə etdiyinizə görə). Aşağıdakı script aşağıdakıları edir:

 // ==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); 

Bütün dinləyiciləri siyahıya aldığımız zaman 299 hadisə dinləyicisi var. Bir neçə dublikat var, amma həqiqətən dublikatlar olub olmadığını bilmirəm. Hər bir hadisənin növü təkrarlanmır, belə ki, bütün bu "təkrarlanan" fərdi dinləyici ola bilər.

2019

tags bağlı digər suallar və ya bir sual