Jak znaleźć detektory zdarzeń w węźle DOM podczas debugowania lub z kodu JavaScript?

840

Mam stronę, na której niektóre detektory zdarzeń są dołączone do pól wprowadzania i pól wyboru. Czy istnieje sposób, aby dowiedzieć się, które detektory zdarzeń obserwują dany węzeł DOM i dla którego zdarzenia?

Wydarzenia są dołączane przy użyciu:

  1. Prototypowe Event.observe ;
  2. DOM addEventListener;
  3. Jako atrybut elementu element.onclick.
Navneet
źródło
3
W jaki sposób wydarzenia są na pierwszym miejscu? Czy korzystasz z biblioteki (np. Prototyp, jQuery itp.)?
Crescent Fresh
Ważne jest, aby pamiętać, że wiele funkcji oddzwaniania może być dołączonych do tego samego typu zdarzenia za pośrednictwem element.addEventListener(type, callback, [bubble]), a element.onclick = functionnadpisuje się za każdym razem, gdy przypisujesz.
Braden Best

Odpowiedzi:

507

Jeśli chcesz tylko sprawdzić, co dzieje się na stronie, możesz wypróbować bookmarklet Event wizualny .

Aktualizacja : Visual Event 2 dostępne.

Andrew Hedges
źródło
1
Doskonały! Pokonuje EventBugwtyczkę Firebug .
Robin Maben,
22
Dodaje to do strony miliard elementów. Wiele z nich to obrazy. Jego użyteczność jest znacznie zmniejszona na stronie z wieloma modułami obsługi zdarzeń (moje ma 17k, a Visual Event ładował się około 3 minut).
Tony R
15
Wydaje mi się, że wspomniane rozszerzenie Chrome @ssharma jest dostępne tutaj
kmote
1
Visial Event nie działa, jeśli strona odwołuje się do biblioteki js innej firmy. Zgłasza błąd: XMLHttpRequest nie może załadować A.com/js/jquery-ui-1.10.3.custom.js?_=1384831682813 . Origin B.com nie jest dozwolony przez Access-Control-Allow-Origin.
hiway,
5
Wewnętrzne narzędzia programistyczne dla Chrome i FF (F12) mają wbudowaną przeglądarkę zdarzeń! Chrome: na karcie „Elementy” wybierz i element, a po prawej stronie znajdują się: Styl, Obliczony, Słuchacze zdarzeń
oriadam
365

To zależy od tego, jak zdarzenia są dołączone. Dla ilustracji załóżmy, że mamy następujący moduł obsługi kliknięć:

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

Zamierzamy dołączyć go do naszego elementu przy użyciu różnych metod, z których niektóre umożliwiają inspekcję, a inne nie.

Metoda A) moduł obsługi pojedynczego zdarzenia

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

Metoda B) obsługa wielu zdarzeń

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

Metoda 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 (przechowuje moduł obsługi w obiekcie)

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

(Zobacz jQuery.fn.datai jQuery.data)

Metoda D): Prototyp (niechlujny)

$(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 do 1.6.0.3 włącznie (tutaj było bardzo trudno)

    // 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 (trochę lepiej)

    // inspect
    var clickEvents = element.getStorage().get('prototype_event_registry').get('click');
    clickEvents.each(function(wrapper){
        alert(wrapper.handler) // alerts "function() { alert('clicked!') }"
    })
    
Półksiężyc Świeży
źródło
3
Dziękujemy za aktualizację. To niefortunne, że musisz iterować przez każdy typ modułu obsługi.
Keith Bentrup
4
Na „metodzie B” (addEventListener) znajduje się odpowiedź dotycząca statusu funkcji wyliczania dla procedur obsługi zarejestrowanych z czystym interfejsem API zdarzeń DOM: stackoverflow.com/questions/7810534/…
Nickolay
@John: dzięki za komentarz. Masz przykład „prawdziwego JavaScriptu” do pobierania słuchaczy dodanych wcześniej addEventListener?
Crescent Fresh,
6
@ Jan, to nie wydaje się działać w przypadku jQuery 1.7.2, czy istnieje inne podejście do tej wersji?
tomdemuyt
14
@tomdemuyt W jQuery zdarzenia są teraz przechowywane w wewnętrznej tablicy danych, a nie są dostępne za pośrednictwem, .data('events')jak były wcześniej. Aby uzyskać dostęp do wewnętrznych danych zdarzeń, użyj $._data(elem, 'events'). Zauważ, że ta funkcja jest oznaczona jako „tylko do użytku wewnętrznego” w źródle jQuery, więc nie obiecuję, że zawsze będzie działać w przyszłości, ale wierzę, że działała od jQuery 1.7 i nadal działa.
Matt Browne
350

Obsługa Chrome, Firefox, Vivaldi i Safari getEventListeners(domElement)w konsoli narzędzi programisty.

Można to wykorzystać do większości celów debugowania.

Poniżej znajduje się bardzo dobre odniesienie do korzystania z niego: https://developers.google.com/web/tools/chrome-devtools/console/utilities#geteventlisteners

Raghav
źródło
1
+1. Kod specyficzny dla przeglądarki nie stanowi dla mnie problemu, ponieważ próbuję uzyskać stronę, której nie kontroluję, aby działała poprawnie.
Grault
9
fajnie, ale działa tylko w wierszu poleceń konsoli Chrome :(
gillyspy
5
@Raghav ah dzięki, użycie NIE jest : tak jak na początku myślałem :)getEventListeners(object) obj getEventListeners()
jave.web
11
Mógłbyś mi zaoszczędzić 3 godziny, gdybyś wyjaśnił, jak uzyskać kod źródłowy list zdarzeń. To „odniesienie” niczego nie wyjaśniło. W przypadku, gdy ktoś był na straty oto jak: var list = getEventListeners(document.getElementById("YOURIDHERE")); console.log(list["focus"][0]["listener"].toString()). Zmień „focus” na wydarzenie, które chcesz sprawdzić, i numer, jeśli na tym samym wydarzeniu jest wielu słuchaczy.
doABarrelRoll721
46
WSKAZÓWKA: getEventListeners($0)sprawi, że nasłuchiwania zdarzeń będą dotyczyły elementu, na którym skupiłeś się w narzędziach programistycznych Chrome. Używam tego cały czas. Uwielbiam nie używać funkcji querySelector ani get__By_
kodera
91

Teraz robi to WebKit Inspector w przeglądarkach Chrome lub Safari. Wyświetli detektory zdarzeń dla elementu DOM po wybraniu go w panelu Elementy.

Ishan
źródło
9
Nie jestem pewien, czy pokazuje wszystkie programy obsługi zdarzeń; tylko jeden moduł obsługi zdarzeń HTML.
huyz
3
Powinienem wspomnieć o wtyczce EventBug dla Firebug dla kompletności < softwareishard.com/blog/category/eventbug >
Nickolay
To właśnie sprawiło, że mój dzień, jakiś starszy prototypowy kod miał wiele funkcji powiązanych z tym samym zdarzeniem na tym samym elemencie, a ja chciałem ich wyśledzić. Dziękuję bardzo Ishan.
siliconrockstar
70

Możliwe jest wyświetlenie listy wszystkich detektorów zdarzeń w JavaScript: To nie jest takie trudne; musisz tylko zhakować prototypemetodę elementów HTML ( przed dodaniem detektorów).

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

Teraz każdy element anchor ( a) będzie miał lastListenerInfowłaściwość, która zawiera wszystkie jego detektory. Działa nawet do usuwania słuchaczy z anonimowymi funkcjami.

Ivan Castellanos
źródło
4
Ta metoda nie będzie działać, jeśli piszesz skrypt użytkownika lub skrypt treści. W dzisiejszych czasach istnieje nie tylko możliwość piaskownicy, ale w jaki sposób możesz zagwarantować kolejność wykonania?
huyz
ta metoda działa z chrome / 19 i FF / 12. kolejność wykonywania może być zagwarantowana, jeśli
zaczepisz o
8
Nie możesz po prostu zmodyfikować Node.prototype? I tak właśnie HTMLAnchorElementdziedziczy .addEventListener.
Esailija,
3
Zakładasz, że agent użytkownika implementuje dziedziczenie prototypów dla obiektów hosta DOM i umożliwia ich modyfikację. Żaden z nich nie jest dobrym pomysłem: nie modyfikuj obiektów, których nie posiadasz .
RobG
1
Jest to dość bezużyteczne - pokazuje, które zdarzenia EventListeners zostały dodane, co może być dobre w niektórych przypadkach, ale nie to, co zostało usunięte. Więc jeśli próbujesz debugować to, co zostało usunięte, a co nie, po prostu nie ma sposobu.
gotofritz
52

Użyj getEventListeners w Google Chrome :

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));
Pranay Soni
źródło
1
Uncaught ReferenceError: getEventListeners nie jest zdefiniowany
Bryan Grace
3
getEventListeners działa tylko w konsoli devtools Chrome. A to jest kopia bardziej szczegółowej odpowiedzi: stackoverflow.com/a/16544813/1026
Nickolay
41

(Przepisanie odpowiedzi na to pytanie, ponieważ jest ono tutaj istotne).

Podczas debugowania, jeśli chcesz tylko zobaczyć wydarzenia, polecam albo ...

  1. Wydarzenie wizualne
  2. Sekcja Elementy w Narzędziach programisty Chrome: wybierz element i poszukaj „Detektory zdarzeń” w prawym dolnym rogu (podobnie w przeglądarce Firefox)

Jeśli chcesz użyć zdarzeń w kodzie i używasz jQuery przed wersją 1.8 , możesz użyć:

$(selector).data("events")

zdobyć wydarzenia. Począwszy od wersji 1.8, używanie .data („zdarzenia”) jest przerywane (patrz ten zgłoszenie błędu ). Możesz użyć:

$._data(element, "events")

Kolejny przykład: zapisz wszystkie zdarzenia kliknięcia w określonym łączu do konsoli:

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

(patrz działający przykład na http://jsfiddle.net/HmsQC/ )

Niestety, użycie danych $ ._ nie jest zalecane, z wyjątkiem debugowania, ponieważ jest to wewnętrzna struktura jQuery i może ulec zmianie w przyszłych wydaniach. Niestety nie znam innych łatwych sposobów uzyskania dostępu do wydarzeń.

Łukasz
źródło
1
$._data(elem, "events")nie działa z jQuery 1.10, przynajmniej w przypadku zdarzeń zarejestrowanych przy użyciu $(elem).on('event', ...). Czy ktoś wie, jak je debugować?
Marius Gedminas,
4
Nie jestem pozytywny, ale myślę, że pierwszym parametrem $._datamoże być element, a nie obiekt jQuery. Muszę więc naprawić mój powyższy przykładconsole.log($._data($myLink[0], "events").click);
Luke
29

1: Prototype.observeużywa Element.addEventListener (zobacz kod źródłowy )

2: Możesz przesłonić, Element.addEventListeneraby zapamiętać dodane detektory (przydatna właściwość EventListenerListzostała usunięta z propozycji specyfikacji DOM3). Uruchom ten kod przed dołączeniem jakiegokolwiek zdarzenia:

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

Przeczytaj wszystkie wydarzenia według:

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

I nie zapomnij zastąpić, Element.removeEventListeneraby usunąć zdarzenie z niestandardowego Element.eventListenerList.

3: Element.onclicknieruchomość wymaga tutaj szczególnej opieki:

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

4: nie zapomnij Element.onclickatrybutu content: są to dwie różne rzeczy:

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

Musisz więc sobie z tym poradzić:

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

Bookmarklet zdarzenia wizualnego (wspomniany w najpopularniejszej odpowiedzi) kradnie tylko pamięć podręczną procedury obsługi bibliotek:

Okazuje się, że nie ma standardowej metody zapewnianej przez zalecany przez W3C interfejs DOM, aby dowiedzieć się, jakie detektory zdarzeń są dołączone do konkretnego elementu. Chociaż może się to wydawać niedopatrzeniem, pojawiła się propozycja włączenia właściwości o nazwie eventListenerList do specyfikacji DOM poziomu 3, ale niestety została ona usunięta w późniejszych wersjach roboczych. W związku z tym jesteśmy zmuszeni przyjrzeć się poszczególnym bibliotekom JavaScript, które zazwyczaj przechowują pamięć podręczną dołączonych zdarzeń (aby można je później usunąć i wykonać inne przydatne abstrakty).

Jako taki, aby Visual Event mógł wyświetlać zdarzenia, musi być w stanie parsować informacje o zdarzeniu z biblioteki JavaScript.

Przesłanianie elementów może być wątpliwe (np. Ponieważ istnieją pewne funkcje specyficzne dla DOM, takie jak kolekcje na żywo, których nie można zakodować w JS), ale daje natywną obsługę eventListenerList i działa w Chrome, Firefox i Opera (nie działa w IE7 ).

Jan Turoň
źródło
23

Możesz owinąć natywne metody DOM do zarządzania detektorami zdarzeń, umieszczając to na górze <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

Jon z
źródło
Popraw mnie, jeśli się mylę, ale czy nie dotyczy to tylko detektorów zdarzeń podłączonych do okna?
Maciej Krawczyk
@MaciejKrawczyk tak, i ci, którzy bańki
Jon z
18

Narzędzia programistyczne Firefoksa teraz to robią. Zdarzenia są wyświetlane po kliknięciu przycisku „ev” po prawej stronie wyświetlacza każdego elementu, w tym zdarzenia jQuery i DOM .

Zrzut ekranu przycisku nasłuchiwania zdarzeń narzędzi programistycznych Firefoksa w zakładce inspektora

simonzack
źródło
Spojrzałem na jeden z elementów domena na stronie, w której bookmarklet Visual Event 2 pokazuje zdarzenie podłączone, i widziałem mały przycisk „ev” po prawej stronie, tak jak ty.
Eric
Odbiornik zdarzeń Firefoksa może dowiedzieć się o zdarzeniach delegowanych przez jQuery, podczas gdy Chrome potrzebuje do tego wtyczki.
Nick Tsai
12

Jeśli masz Firebug , możesz użyć console.dir(object or array)do wydrukowania ładnego drzewa w dzienniku konsoli dowolnego skalaru JavaScript, tablicy lub obiektu.

Próbować:

console.dir(clickEvents);

lub

console.dir(window);
Michael Butler
źródło
9
Nowa funkcja w firebug 1.12 getfirebug.com/wiki/index.php/GetEventListeners
Javier Constanzo
10

W pełni działające rozwiązanie oparte na odpowiedzi Jana Turona - zachowuje się jak getEventListeners()z konsoli:

(Jest mały błąd z duplikatami. I tak niewiele się psuje.)

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

Stosowanie:

someElement.getEventListeners([name]) - zwraca listę detektorów zdarzeń, jeśli nazwa jest ustawiona, zwraca tablicę detektorów dla tego zdarzenia

someElement.clearEventListeners([name]) - usuń wszystkie detektory zdarzeń, jeśli nazwa jest ustawiona, usuń tylko detektory tego zdarzenia

n00b
źródło
3
To ładna odpowiedź, ale nie mogę zmusić jej do pracy nad elementami bodyi document.
David Bradshaw,
Naprawdę fajne rozwiązanie!
Dzhakhar Ukhaev
@Peter Mortensen, dlaczego zmieniłeś nazwisko Jana? :)
n00b
1
@David Bradshaw: ponieważ ciało, dokument i okno mają własny prototyp, a nie prototyp Element ...
Stefan Steiger
1
@ n00b: Wystąpił błąd. Dlatego hmmm. Używasz operatora przecinka w instrukcji if dla detektora i useCaption ... Operator przecinka ocenia każdy ze swoich operandów (od lewej do prawej) i zwraca wartość ostatniego operandu. Usuwasz więc pierwszy eventListener, który pasuje do useCapture, niezależnie od rodzaju zdarzenia ... Powinno to być && zamiast przecinka.
Stefan Steiger,
8

Opera 12 (nie najnowszy silnik Chrome Webkit) Dragonfly ma to od dłuższego czasu i jest oczywiście wyświetlane w strukturze DOM. Moim zdaniem jest to doskonały debugger i jest to jedyny powód, dla którego nadal używam wersji Opery 12 (nie ma wersji v13, v14, a wersja v15 Webkit wciąż nie ma Dragonfly)

wprowadź opis zdjęcia tutaj

Daniel Sokołowski
źródło
4

Prototypowy sposób 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];
}
Ronald
źródło
4

Ostatnio pracowałem z wydarzeniami i chciałem wyświetlić / kontrolować wszystkie zdarzenia na stronie. Po przeanalizowaniu możliwych rozwiązań postanowiłem pójść własną drogą i stworzyć niestandardowy system monitorowania zdarzeń. Zrobiłem więc trzy rzeczy.

Po pierwsze potrzebowałem kontenera dla wszystkich detektorów zdarzeń na stronie: to jest EventListenersobiekt. Ma trzy użyteczne metody: add(), remove(), i get().

Następnie stworzyłem EventListenerobiekt do przechowywania informacji niezbędnych do zdarzenia, czyli: target, type, callback, options, useCapture, wantsUntrusted, i dodaje metodę remove()usuwania słuchacza.

Na koniec rozszerzyłem język macierzysty addEventListener()i removeEventListener()metody, aby działały z obiektami, które utworzyłem ( EventListeneri EventListeners).

Stosowanie:

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

// bodyClickEvent.remove();

addEventListener()tworzy EventListenerobiekt, dodaje go EventListenersi zwraca EventListenerobiekt, aby można go było później usunąć.

EventListeners.get()można użyć do wyświetlenia słuchaczy na stronie. Akceptuje EventTargetciąg lub ciąg znaków (typ zdarzenia).

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

Próbny

Powiedzmy, że chcemy poznać każdego detektora zdarzeń na bieżącej stronie. Możemy to zrobić (zakładając, że używasz rozszerzenia menedżera skryptów, w tym przypadku Tampermonkey). Następujący skrypt to robi:

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

A kiedy podajemy listę wszystkich słuchaczy, mówi się, że jest 299 słuchaczy zdarzeń. „Wydaje się”, że są jakieś duplikaty, ale nie wiem, czy naprawdę są duplikatami. Nie każdy typ zdarzenia jest duplikowany, więc wszystkie te „duplikaty” mogą być pojedynczymi detektorami.

zrzut ekranu konsoli z listą wszystkich detektorów zdarzeń na tej stronie

Kod można znaleźć w moim repozytorium. Nie chciałem go tutaj zamieszczać, ponieważ jest raczej długi.


Aktualizacja: Wydaje się, że to nie działa z jQuery. Kiedy badam EventListener, widzę, że jest to wywołanie zwrotne

function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}

Uważam, że należy to do jQuery i nie jest rzeczywistym wywołaniem zwrotnym. jQuery przechowuje rzeczywiste wywołanie zwrotne we właściwościach EventTarget:

$(document.body).click(function () {
    console.log("jquery click");
});

wprowadź opis zdjęcia tutaj

Aby usunąć detektor zdarzeń, faktyczne wywołanie zwrotne musi zostać przekazane do removeEventListener()metody. Aby więc działał z jQuery, wymaga dalszych modyfikacji. Mogę to naprawić w przyszłości.

akinuri
źródło
Działa świetnie! Dzięki
mt025
3

Próbuję to zrobić w jQuery 2.1, a $().click() -> $(element).data("events").click;metoda „ ” nie działa.

Zrozumiałem, że w moim przypadku działają tylko funkcje $ ._ data ():

	$(document).ready(function(){

		var node = $('body');
		
        // Bind 3 events to body click
		node.click(function(e) { alert('hello');  })
			.click(function(e) { alert('bye');  })
			.click(fun_1);

        // Inspect the events of body
		var events = $._data(node[0], "events").click;
		var ev1 = events[0].handler // -> function(e) { alert('hello')
		var ev2 = events[1].handler // -> function(e) { alert('bye')
		var ev3 = events[2].handler // -> function fun_1()
        
		$('body')
			.append('<p> Event1 = ' + eval(ev1).toString() + '</p>')
			.append('<p> Event2 = ' + eval(ev2).toString() + '</p>')
			.append('<p> Event3 = ' + eval(ev3).toString() + '</p>');        
	
	});

	function fun_1() {
		var txt = 'text del missatge';	 
		alert(txt);
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>
</body>

Joel Barba
źródło
1

zmiana tych funkcji pozwoli ci zalogować dodane nasłuchiwania:

EventTarget.prototype.addEventListener
EventTarget.prototype.attachEvent
EventTarget.prototype.removeEventListener
EventTarget.prototype.detachEvent

przeczytaj resztę słuchaczy

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
Aiden Waterman
źródło