Ottieni listener di eventi collegati al nodo utilizzando addEventListener


106

Ho già esaminato queste domande:

tuttavia nessuno di loro risponde come ottenere un elenco di listener di eventi collegati a un nodo utilizzando addEventListener, senza modificare il addEventListenerprototipo prima che i listener di eventi vengano creati.

VisualEvent non visualizza tutti i listener di eventi (quelli specifici per iPhone) e voglio farlo (in qualche modo) a livello di programmazione.



"in qualche modo a livello di programmazione" e il fatto che la risposta accettata per questa domanda sia una caratteristica di devtools rende questo un duplicato della domanda elencata. Per chi cerca una soluzione JS, la risposta è "non ce n'è una"
Nickolay

Risposte:


135

Chrome DevTools, Safari Inspector e Firebug supportano getEventListeners (nodo) .

getEventListeners (documento)


6
Voglio notare che il metodo getEventListeners non supporta la versione di Firefox 35.
MURATSPLAT

Potrebbe non funzionare su Firefox, ma di nuovo gli sviluppatori si sviluppano su più browser / Questo aiuta sicuramente se è necessario modificare un sito esistente ... MOLTO!
JasonXA

1
Non è Firefox 69.
Vitaly Zdanevich

65

Non puoi.

L'unico modo per ottenere un elenco di tutti i listener di eventi collegati a un nodo è intercettare la chiamata dell'allegato del listener.

AddEventListener DOM4

Dice

Aggiungi un listener di eventi all'elenco associato di listener di eventi con il tipo impostato su type, listener impostato su listener e capture impostato su capture, a meno che non sia già presente un listener di eventi in quell'elenco con lo stesso tipo, listener e acquisizione.

Significa che un listener di eventi viene aggiunto all '"elenco dei listener di eventi". È tutto. Non c'è idea di cosa dovrebbe essere questo elenco né di come accedervi.


12
C'è qualche possibilità di fornire qualche giustificazione o ragionamento sul perché deve funzionare in questo modo? Chiaramente il browser sa cosa sono tutti gli ascoltatori.
Darth Egregious

3
@ user973810: Come vuoi che lo giustifichi? L'API DOM non fornisce alcun modo per farlo e non ci sono modi non standard per farlo nei browser attuali. Quanto al motivo per cui questo è il caso, non lo so davvero. Sembra una cosa ragionevole da voler fare.
Tim Down

Ho visto alcuni thread in giro sull'aggiunta di un'API al DOM per questo.
Raynos

@TimDown la modifica aiuta. Vedere che non ci sono specifiche per qualcosa come "getEventListeners" giustifica il motivo per cui non esiste una cosa del genere.
Darth Egregious

24

Poiché non esiste un modo nativo per farlo, ecco la soluzione meno invadente che ho trovato (non aggiungere alcun metodo prototipo "vecchio"):

var ListenerTracker=new function(){
    var is_active=false;
    // listener tracking datas
    var _elements_  =[];
    var _listeners_ =[];
    this.init=function(){
        if(!is_active){//avoid duplicate call
            intercep_events_listeners();
        }
        is_active=true;
    };
    // register individual element an returns its corresponding listeners
    var register_element=function(element){
        if(_elements_.indexOf(element)==-1){
            // NB : split by useCapture to make listener easier to find when removing
            var elt_listeners=[{/*useCapture=false*/},{/*useCapture=true*/}];
            _elements_.push(element);
            _listeners_.push(elt_listeners);
        }
        return _listeners_[_elements_.indexOf(element)];
    };
    var intercep_events_listeners = function(){
        // backup overrided methods
        var _super_={
            "addEventListener"      : HTMLElement.prototype.addEventListener,
            "removeEventListener"   : HTMLElement.prototype.removeEventListener
        };

        Element.prototype["addEventListener"]=function(type, listener, useCapture){
            var listeners=register_element(this);
            // add event before to avoid registering if an error is thrown
            _super_["addEventListener"].apply(this,arguments);
            // adapt to 'elt_listeners' index
            useCapture=useCapture?1:0;

            if(!listeners[useCapture][type])listeners[useCapture][type]=[];
            listeners[useCapture][type].push(listener);
        };
        Element.prototype["removeEventListener"]=function(type, listener, useCapture){
            var listeners=register_element(this);
            // add event before to avoid registering if an error is thrown
            _super_["removeEventListener"].apply(this,arguments);
            // adapt to 'elt_listeners' index
            useCapture=useCapture?1:0;
            if(!listeners[useCapture][type])return;
            var lid = listeners[useCapture][type].indexOf(listener);
            if(lid>-1)listeners[useCapture][type].splice(lid,1);
        };
        Element.prototype["getEventListeners"]=function(type){
            var listeners=register_element(this);
            // convert to listener datas list
            var result=[];
            for(var useCapture=0,list;list=listeners[useCapture];useCapture++){
                if(typeof(type)=="string"){// filtered by type
                    if(list[type]){
                        for(var id in list[type]){
                            result.push({"type":type,"listener":list[type][id],"useCapture":!!useCapture});
                        }
                    }
                }else{// all
                    for(var _type in list){
                        for(var id in list[_type]){
                            result.push({"type":_type,"listener":list[_type][id],"useCapture":!!useCapture});
                        }
                    }
                }
            }
            return result;
        };
    };
}();
ListenerTracker.init();

Dovresti anche fare in modo che intercetti i listener di eventi della finestra. Oltre a questo, funziona benissimo!

2

Puoi ottenere tutti gli eventi jQuery utilizzando $ ._ data ($ ('[selector]') [0], 'events'); cambia [selettore] con quello che ti serve.

C'è un plugin che raccoglie tutti gli eventi allegati da jQuery chiamato eventsReport.

Inoltre scrivo il mio plugin che lo fa con una migliore formattazione.

Ma comunque sembra che non possiamo raccogliere eventi aggiunti dal metodo addEventListener. È possibile che possiamo eseguire il wrapping della chiamata addEventListener per memorizzare gli eventi aggiunti dopo la nostra chiamata.

Sembra il modo migliore per vedere gli eventi aggiunti a un elemento con strumenti di sviluppo.

Ma non vedrai eventi delegati lì. Quindi abbiamo bisogno di jQuery eventsReport.

AGGIORNAMENTO: ORA POSSIAMO vedere gli eventi aggiunti dal metodo addEventListener VEDERE LA RISPOSTA GIUSTA A QUESTA DOMANDA.


Questa è un'interfaccia privata e deprecata e potrebbe scomparire presto, quindi non fare affidamento su questo.
mgol

1
Sì, ma la volta che ho risposto, non esisteva tale capacità negli strumenti di sviluppo. Quindi, non c'era niente da cui scegliere.
Rantiev

È deprecato @Rantiev, puoi rimuovere quella risposta?
Julio Marins

2

Non riesco a trovare un modo per farlo con il codice, ma in Firefox 64 stock, gli eventi sono elencati accanto a ciascuna entità HTML nel Developer Tools Inspector come indicato nella pagina Examine Event Listeners di MDN e come dimostrato in questa immagine:

screenshot di FF Inspector

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.