Cum de a găsi ascultătorii eveniment pe un nod DOM atunci când depanare sau de cod JavaScript?

Am o pagină în cazul în care un eveniment ascultătorii sunt atașate la cutii de intrare și selectați cutii. Există o modalitate de a afla care ascultătorii eveniment sunt observarea unui anumit nod DOM și pentru ce eveniment?

Evenimentele sunt atașate folosind:

  1. Prototip's Eveniment.observa`;
  2. DOM's addEventListener;
  3. Ca element atribut element.onclick`.
Comentarii la întrebare (2)
Soluția

Dacă aveți nevoie doar pentru a inspecta ce's-a întâmplat pe o pagina, s-ar putea încerca Eveniment Vizual bookmarklet.

Update: Eveniment Vizual 2 disponibil;

Comentarii (13)

Aceasta depinde de modul în care evenimentele sunt atașate. Pentru exemplificare presupunem că avem următoarele click handler:

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

Am're de gând să-l atașați la elementul nostru folosind diferite metode, unele care să permită inspecția și unele care nu't.

Metoda a) single event handler

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

Metoda B) mai multe stivuitoare eveniment

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

// inspecta var clickEvents = $(element).date de("evenimente").faceți clic; jQuery.fiecare(clickEvents, functia(cheie, valoare) { alert(valoare) // alerte "function() { alert('clic!') }" })

  • 1.4.x (magazine handler în interiorul unui obiect)

// inspecta var clickEvents = $(element).date de("evenimente").faceți clic; jQuery.fiecare(clickEvents, functia(cheie, handlerObj) { alert(handlerObj.handler) // alerte "function() { alert('clic!') }" // de asemenea, disponibile: handlerObj.tip, handlerObj.nume })

(a se Vedea jQuery.fn.date și jQuery.date)

Metoda D): Prototip (murdar)

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

// inspecta Eveniment.observatori.fiecare(function(item) { dacă(obiect[0] == element) { alert(articol2) // alerte "function() { alert('clic!') }" } })

  • 1.6 la 1.6.0.3, inclusiv (foarte dificil)

// inspecta. "_eventId" pentru < 1.6.0.3 în timp ce // "_prototypeEventID" a fost introdus în 1.6.0.3 var clickEvents = Eveniment.cache[element._eventId || (element._prototypeEventID|| [])[0]].faceți clic; clickEvents.fiecare(function(wrapper){ alert(wrapper.handler) // alerte "function() { alert('clic!') }" })

  • 1.6.1 (mai bine)

// inspecta var clickEvents = element.getStorage().ia('prototype_event_registry').ia('faceți clic pe'); clickEvents.fiecare(function(wrapper){ alert(wrapper.handler) // alerte "function() { alert('clic!') }" })

Comentarii (8)

Chrome, Firefox, Vivaldi și Safari sprijin `getEventListeners(domElement) în Instrumente de dezvoltare consola.

Pentru majoritatea scopuri de depanare, acest lucru ar putea fi folosit.

Mai jos este o referință foarte bună să-l folosească: https://developers.google.com/web/tools/chrome-devtools/console/utilities#geteventlisteners

Comentarii (9)

WebKit Inspector în Chrome sau Safari browsere acum face acest lucru. Se va afișa ascultătorii eveniment pentru un element DOM atunci când selectați-l în Elemente de panou.

Comentarii (3)

Este posibil pentru a lista toate ascultătorii eveniment în JavaScript: It's nu-i greu; trebuie doar să hack "prototip" 's metoda de elemente HTML (înainte adăugarea de ascultători).

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

Acum, fiecare element de ancorare ("a") va avea un `lastListenerInfo de proprietate care conține toate ascultătorii săi. Și este chiar și lucrează pentru a scoate ascultătorii cu funcții anonime.

Comentarii (8)

Utilizarea getEventListeners în Google Chrome:

getEventListeners(document.getElementByID('btnlogin'));
getEventListeners($('#btnlogin'));
Comentarii (3)

(Rescrierea răspunsul din această întrebare, deoarece's relevante aici.)

Atunci când depanare, dacă doriți doar pentru a vedea evenimente, am recomandăm să fie...

  1. Eveniment Vizual
  2. La Elemente secțiunea de Chrome's Dezvoltator de Instrumente: selectați un element și uita-te pentru "Ascultătorii Eveniment" pe partea din dreapta jos (similar în Firefox)

Dacă doriți să utilizați evenimente în codul dvs., și sunteți folosind jQuery înainte de versiunea 1.8, puteți folosi:

$(selector).data("events")

pentru a obține evenimente. Începând cu versiunea 1.8, folosind .date de("evenimente") este întrerupt (a se vedea acest bug bilet). Puteți folosi:

$._data(element, "events")

Un alt exemplu: Scrie toate evenimente click pe un anumit link-ul de la consola:

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

(a se vedea http://jsfiddle.net/HmsQC/ pentru un exemplu de lucru)

Din păcate, utilizarea $._data acest lucru nu este recomandat cu excepția pentru depanare, deoarece acesta este un intern jQuery structura, și-ar putea schimba în viitor versiuni. Din păcate nu cunosc nici un alt mijloc ușor de a accesa evenimente.

Comentarii (2)

1: Prototip.observa folosește un Element.addEventListener (a se vedea codul sursă)

2: puteți suprascrie Element.addEventListener să-și amintească adăugat ascultători (la îndemână proprietatea EventListenerList a fost scos din DOM3 spec propunere). Rula acest cod înainte de orice eveniment este atașat:

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

Citiți toate evenimentele de:

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

Și don't uita pentru a trece peste Element.removeEventListener pentru a elimina eveniment de personalizat Element.eventListenerList.

3: `Element.onclick proprietatea are nevoie de îngrijire specială aici:

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

4: don't uita Element.onclick conținutul atribut: acestea sunt două lucruri diferite:

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

Deci, ai nevoie să-l ocupe, de asemenea:

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

La Eveniment Vizual bookmarklet (menționat în cel mai popular răspuns) doar fură bibliotecă personalizat handler cache:

Se pare că nu există o metodă standard furnizate de către W3C recomandat DOM interfață pentru a afla ce ascultătorii eveniment sunt atașat la un anumit element. În timp ce acest lucru poate părea a fi o de supraveghere, nu a fost o propunere de a include o proprietate numita eventListenerList la nivelul 3 DOM caietul de sarcini, dar a fost din păcate, a fost eliminat în mai târziu proiecte. Ca atare, suntem nevoiți să privit la nivel individual biblioteci Javascript, care de obicei menține un cache de atașat evenimente (astfel încât acestea pot fi ulterior eliminate și de a efectua alte utile abstracții).

Ca atare, în scopul de Eveniment Vizual pentru a arăta evenimente, acesta trebuie să fie capabil să analiza informații eveniment dintr-o bibliotecă Javascript.

Element imperative poate fi pusă la îndoială (de exemplu, pentru că există unele DOM caracteristici specifice, cum ar fi live colecții, care nu pot fi codificate în JS), dar oferă eventListenerList suport nativ și funcționează în Chrome, Firefox și Opera (nu't de muncă în IE7).

Comentarii (0)

Ai putea folie nativ DOM metode pentru gestionarea eveniment ascultătorilor de a pune acest lucru în partea de sus a <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

Comentarii (2)

Firefox developer tools acum face acest lucru. Evenimentele sunt afișate făcând clic pe "ev" buton de pe partea dreaptă a fiecărui element's de afișare, inclusiv jQuery și DOM evenimente.

Comentarii (2)

Dacă aveți Firebug, puteți folosi consola.dir(obiect sau matrice)` pentru a imprima un copac frumos in consola jurnal de orice JavaScript scalar, matrice, sau un obiect.

Încercați:

console.dir(clickEvents);

sau

console.dir(window);
Comentarii (1)

Complet de lucru de soluție bazată pe [răspunde de Jan Turon][1] - se comportă ca getEventListeners() din consola:

(Există un mic bug cu duplicate. Nu't pauză de mult, oricum.)


(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
Comentarii (5)

Opera 12 (nu cele mai recente Chrome Webkit motorul de baza) Libelula a avut acest lucru pentru un timp și este evident afișate în structura DOM. În opinia mea, este un superior debugger și este singurul motiv pentru care rămase de ce eu încă mai folosesc Opera 12 versiunea de bază (nu există nici v13, v14 și versiunea v15 bazate pe Webkit nu are Libelula încă)

Comentarii (0)

Recent am fost de lucru cu evenimente și a vrut pentru a putea vizualiza și/sau de a controla toate evenimentele într-o pagină. M-am uitat la soluțiile posibile, am'am decis să merg pe drumul meu și de a crea un sistem personalizat pentru a monitoriza evenimente. Deci, am făcut trei lucruri.

În primul rând, am nevoie de un container pentru toate ascultătorii eveniment în pagina: care's'EventListenersobiect. Ea are trei metode utile:add(),remove ()", și " get()`.

Apoi, am creat un EventListenerobiect să dețină informațiile necesare pentru eveniment, și anume: "țintă", "tip",callback,opțiuni,useCapture,wantsUntrusted, și a adăugat o metodăremove()` pentru a elimina ascultător.

În cele din urmă, mi-am prelungit nativ addEventListener () " și "removeEventListener() metode pentru a le face de lucru cu obiectele I'am creat (EventListener" și " EventListeners).

Utilizare:

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

// bodyClickEvent.remove();

addEventListener () creează un EventListener obiect, adaugă-l la EventListeners și returnează EventListener obiect, astfel încât acesta poate fi eliminat mai târziu.

EventListeners.obține() poate fi folosit pentru a vizualiza ascultători, în pagina. Se acceptă un EventTarget` sau un șir de caractere (tipul de eveniment).

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

Demo

Las's spunem că vreau să știu fiecare ascultător eveniment in aceasta pagina curentă. Putem face asta (presupunand ca're folosind un script manager de extensie, Tampermonkey în acest caz). Următorul script face acest lucru:

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

Și când vom lista toate ascultătorii, se spune că există 299 ascultătorii eveniment. Acolo "pare" să fie niște duplicate, dar eu nu't știu dacă au're într-adevăr duplicate. Nu orice tip de eveniment este duplicat, deci toate acele "duplicate" ar putea fi un individ ascultător.

Cod pot fi găsite la repository. am n't doriți să-l posta aici, deoarece's destul de lung.


Actualizare: Acest lucru nu't părea pentru a lucra cu jQuery. Când voi examina EventListener, văd că callback este

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

Cred că aceasta aparține jQuery, și nu este efectivă de apel invers. jQuery magazine real de apel invers din lista de proprietăți a EventTarget:

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

Pentru a elimina un ascultător eveniment, real callback trebuie să fi trecut la `removeEventListener () metodă. Deci, în scopul de a face acest lucru cu jQuery, este nevoie de modificări ulterioare. S-ar putea stabili că în viitor.

Comentarii (1)

Prototip 1.7.1 mod

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

Încerc să fac asta în jQuery 2.1, și cu "$().faceți clic pe() -> $(element).date de("evenimente").faceți clic;" metodă nu't de lucru.

Mi-am dat seama că numai $._data() functioneaza in cazul meu :

    $(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>


Comentarii (0)

schimbarea acestor funcții va permite să vă conectați ascultătorii adăugat:

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

citește restul ascultătorilor cu

console.log(someElement.onclick);
console.log(someElement.getAttribute("onclick"));
Comentarii (0)