Pobierz detektory zdarzeń dołączone do węzła za pomocą addEventListener


106

Spojrzałem już na te pytania:

jednak żaden z nich nie odpowiada, jak uzyskać listę detektorów zdarzeń dołączonych do węzła za pomocą addEventListener, bez modyfikowania addEventListenerprototypu przed utworzeniem detektorów zdarzeń.

VisualEvent nie wyświetla wszystkich odbiorników zdarzeń (specyficznych dla iPhone'a ) i chcę to zrobić (nieco) programowo.



"nieco programowo", a fakt, że akceptowaną odpowiedzią na to pytanie jest funkcja devtools, sprawia, że ​​jest to duplikat wymienionego pytania. Dla tych, którzy szukają rozwiązania JS, odpowiedź brzmi: „nie ma takiego”
Nickolay,

Odpowiedzi:


135

Chrome DevTools, Safari Inspector i Firebug obsługują getEventListeners (node) .

getEventListeners (dokument)


6
Chcę zauważyć, że metoda getEventListeners nie obsługuje wersji przeglądarki Firefox 35.
MURATSPLAT

To może nie działać na Firefoksie, ale potem znowu deweloperzy rozwijają się na wielu przeglądarkach / To na pewno POMAGA, jeśli trzeba zmodyfikować istniejącą witrynę ... DUŻO!
JasonXA

1
Nie to Firefox 69.
Witalij Zdanevich

65

Nie możesz.

Jedynym sposobem uzyskania listy wszystkich detektorów zdarzeń podłączonych do węzła jest przechwycenie wywołania załącznika nasłuchującego.

DOM4 addEventListener

Mówi

Dołącz detektor zdarzeń do skojarzonej listy detektorów zdarzeń z typem ustawionym na typ, odbiornikiem ustawionym na detektor i przechwytywanym ustawionym na przechwytywanie, chyba że na tej liście znajduje się już detektor zdarzeń o tym samym typie, nasłuchiwaniu i przechwytywaniu.

Oznacza to, że detektor zdarzeń jest dodawany do „listy detektorów zdarzeń”. To wszystko. Nie ma pojęcia, jaka powinna być ta lista ani jak należy uzyskać do niej dostęp.


12
Czy jest jakaś szansa na uzasadnienie lub uzasadnienie, dlaczego musi to działać w ten sposób? Najwyraźniej przeglądarka wie, kim są wszyscy słuchacze.
Darth Egregious,

3
@ user973810: Jak chcesz, żeby to uzasadnił? DOM API nie daje takiej możliwości i nie ma niestandardowych sposobów na zrobienie tego w obecnych przeglądarkach. Nie wiem, dlaczego tak się dzieje. Chęć zrobienia wydaje się rozsądna.
Tim Down

Widziałem kilka wątków na temat dodawania API do DOM w tym celu.
Raynos,

@TimDown edycja pomaga. Fakt, że nie ma specyfikacji dla czegoś takiego jak „getEventListeners”, uzasadnia, dlaczego czegoś takiego nie ma.
Darth Egregious,

24

Ponieważ nie ma natywnego sposobu, aby to zrobić, oto mniej uciążliwe rozwiązanie, które znalazłem (nie dodawaj żadnych `` starych '' metod prototypowych):

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

Powinieneś także sprawić, by przechwytywał detektory zdarzeń okna. Poza tym działa świetnie!

2

Możesz uzyskać wszystkie zdarzenia jQuery za pomocą $ ._ data ($ ('[selector]') [0], 'events'); zmień [selector] na to, czego potrzebujesz.

Istnieje wtyczka zbierająca wszystkie zdarzenia dołączone przez jQuery o nazwie eventsReport.

Piszę również własną wtyczkę, która robi to z lepszym formatowaniem.

W każdym razie wygląda na to, że nie możemy zebrać zdarzeń dodanych metodą addEventListener. Być może możemy zawinąć wywołanie addEventListener, aby zapisać zdarzenia dodane po naszym wywołaniu zawijania.

Wydaje się, że jest to najlepszy sposób, aby zobaczyć zdarzenia dodane do elementu za pomocą narzędzi programistycznych.

Ale nie zobaczysz tam delegowanych wydarzeń. Więc potrzebujemy jQuery eventsReport.

AKTUALIZACJA: TERAZ Widzimy zdarzenia dodane przez metodę addEventListener ZOBACZ PRAWĄ ODPOWIEDŹ NA TO PYTANIE.


To jest prywatny i przestarzały interfejs i może wkrótce zniknąć, więc nie polegaj na tym.
mgol

1
Tak, ale kiedy odpowiadałem, nie było takiej możliwości w narzędziach deweloperskich. Więc nie było z czego wybierać.
Rantiev

@Rantiev jest przestarzała, czy możesz usunąć tę odpowiedź?
Julio Marins,

2

Nie mogę znaleźć sposobu, aby to zrobić za pomocą kodu, ale w przeglądarce Firefox 64 zdarzenia są wymienione obok każdej jednostki HTML w Inspektorze narzędzi programistycznych, jak zaznaczono na stronie Sprawdzanie detektorów zdarzeń MDN i jak pokazano na tym obrazku:

zrzut ekranu z FF Inspector

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.