2014-09-06 19 views
6

Chcę móc przechwytywać wszystkie zdarzenia, które zostały utworzone i wysłane oraz wywołać niektóre wywołania zwrotne, gdy tak się stanie.Przechwytuj wszystkie zdarzenia (javascript)

Chciałbym również móc wywołać wywołanie zwrotne za każdym razem, gdy zdarzenie jest sparowane z detektorem zdarzeń.

Problemy obejmują: dynamicznie dodawane elementy, zdarzenia, których propagacja lub propagacja jest wyłączona, oraz zdarzenia niestandardowe generowane dynamicznie. Wyobrażam sobie, że musiałby być prototypowanie dispatchEvent lub coś takiego, ale nie jestem pewien. Czy to możliwe?

+1

Tak, pierwsze pytanie: dlaczego? To cudowne, że chcesz to zrobić, ale jest też bardzo dziwne. –

+1

Niezależnie od tego, jaki problem jest wymagany, są one prawdopodobnie lepszą alternatywą. Możesz łatwo poradzić sobie z wydarzeniami syntetycznymi, a także elementami tworzonymi dynamicznie (istnieją sposoby wykrywania kiedy tworzony jest element). – Markasoftware

+4

To brzmi całkiem fajnie. nie słuchajcie innych, którzy was poniżają. –

Odpowiedz

2

Pewne podstawy zdarzeń:

  1. Zdarzenia są wysyłane „na” obiekt DOM (zwykle elementu), który jest celem zdarzenia.
  2. Zdarzenia mogą być najpierw propagowane w dół do elementów potomnych w fazie przechwytywania. Ta faza jest rzadko używana, ponieważ do niedawna nie była obsługiwana przez niektóre szeroko używane przeglądarki.
  3. Zdarzenia można następnie propagować do elementów nadrzędnych w fazie propagacji. Ta faza jest powszechnie stosowana.
  4. Niektóre zdarzenia nie są propagowane, nie mają fazy przechwytywania ani fazy bubble (np. Fokus, rozmycie i przesyłanie zdarzeń). Niektóre zdarzenia propagowane w niektórych przeglądarkach nie rozprzestrzeniają się w innych.
  5. Elementy DOM, które odpowiadają na zdarzenia, mają funkcję obsługi zdarzeń. Można go ustawić tak, aby nasłuchiwał określonych zdarzeń i wywoływał funkcję detektora, gdy to zdarzenie dotrze do elementu, albo podczas przechwytywania, bulgotania lub jeśli element jest celem zdarzenia.
  6. Słuchacze mogą anulować propagację, np. zdarzenie click na rozpiętości wewnątrz linkiem można anulować propagację więc link nie dostać kliknięcie

Biorąc powyższe pod uwagę, że jest to praktyczna niemożliwość „przechwytywać wszystkie zdarzenia” Korzystanie z Events API. Wymagałoby to ustanowienia detektora dla każdego typu zdarzenia na każdym elemencie i niemożliwe jest przechwycenie zdarzeń niestandardowych, ponieważ musisz wiedzieć o nich, aby ustawić odpowiedniego słuchacza.

Wyobrażam tam musiałyby być prototypowanie dispatchEvent lub coś

dispatchEvent to metoda wystąpienie zdarzenia, to nie jest określony jako konstruktor (nie ma wymogu dla niego mieć wewnętrzną metodę [[Construct]]), więc nie jest praktyczne w użyciu jako takie. Przeglądarki nie są wymagane do implementacji dziedziczenia prototypów dla obiektów hosta (choć większość robi), a szczegóły implementacji obiektów i metod hosta są w dużej mierze ukryte, więc nie jest to opcja.

Możesz spróbować rozszerzyć interfejs API zdarzeń, ale naprawdę chcesz should not mess with host objects.

Wygląda na to, że niepokoją Cię dynamicznie dodawane elementy. Istnieje strategia o nazwie "event delegation", w której należy opracować zdarzenia, których należy posłuchać, a następnie skonfigurować obiekty odsłuchowe tak blisko obiektów zdarzeń, jak to możliwe w przypadku elementu, który się nie zmienia (np. Element tabeli, jeśli dynamicznie dodajesz i usuwanie wierszy tabeli lub div kontenera dla innych elementów) dla określonych typów zdarzeń, na które należy odpowiedzieć.

Możesz także mieć funkcje, które modyfikują zdarzenia niestandardowe wysyłania DOM, aby dodać detektory lub cokolwiek innego.

1

Jeśli naprawdę chcesz to zrobić, możesz zastąpić addEventListener, aby śledzić rejestrowane i uruchamiane zdarzenia.

var myEventManager = (function() { 
    var old = EventTarget.prototype.addEventListener, 
     listeners = [], 
     events = []; 

    EventTarget.prototype.addEventListener = function(type, listener) { 

     function new_listener(listener) { 
      return function(e) { 
       events.push(e);     // remember event 
       return listener.call(this, e); // call original listener 
      }; 
     } 

     listeners.push([type, listener]);  // remember call 
     return old.call(this, type, new_listener(listener)); // call original 
    }; 

    return { 
     get_events: function() { return events; }, 
     get_listeners: function() {return listeners; } 
    }; 

}()); 

Jednakże, istnieje niezliczona ilość powodów, aby nie to zrobić, nie tylko fakt, że będzie szybko zabraknie pamięci, jak nagrywać tysiące wydarzeń, takich jak ruchy myszką. Nie spowoduje to również przechwycenia detektorów zdarzeń w taki sposób, jak elt.onclick. Oczywiście nie złapie też słuchaczy skonfigurowanych za pomocą starego API IE attachEvent. Co najważniejsze, nie pomoże ci to, które zdarzenia są generowane i odsłuchiwane wewnętrznie, na przykład kliknięcie myszą w polu wyboru. (Kompletne rozwiązanie wymagałoby również obsługę removeEventListener.)

Można również zastąpić createEvent i dispatch w podobny sposób, ale znowu, że będzie przechwytywać tylko te wydarzenia, które są wprost stworzone lub wysyłane w kodzie JS.

Jeśli naprawdę chcesz robić to, na co masz ochotę, prawdopodobnie musisz rozwidlić Chrome.

Powiązane problemy