2014-09-06 19 views
6

Desidero essere in grado di catturare tutti gli eventi creati e inviati e attivare alcune richiamate quando ciò accade.Cattura tutti gli eventi (javascript)

Inoltre, vorrei poter attivare una richiamata ogni volta che un evento è associato a un listener di eventi.

I problemi includono: elementi aggiunti in modo dinamico, eventi la cui propagazione o bubbling è impedita e eventi personalizzati generati dinamicamente. Immagino che ci debba essere una prototipazione di dispatchEvent o qualcosa del genere, ma non sono sicuro. È possibile?

+1

Quindi, prima domanda: perché? È meraviglioso che tu voglia farlo, ma è anche molto strano. –

+1

Qualunque sia il problema che richiede questo, sono probabilmente un'alternativa migliore. Puoi gestire facilmente eventi sintetici e anche elementi creati dinamicamente (ci sono modi per rilevare ogni volta che viene creato un elemento) – Markasoftware

+4

Questo suona molto bene. non ascoltare gli altri che ti stanno mettendo giù. –

risposta

2

Alcuni principi fondamentali dell'evento:

  1. eventi vengono spediti "su" un oggetto DOM (di solito un elemento), che è il target dell'evento.
  2. Gli eventi possono inizialmente propagarsi agli elementi figlio in una fase di acquisizione. Questa fase viene utilizzata raramente poiché fino a poco tempo fa non era supportata da alcuni browser ampiamente utilizzati.
  3. Gli eventi possono in seguito propagarsi fino a elementi padre in una fase di bubbling. Questa fase è comunemente usata.
  4. Alcuni eventi non si propagano, non hanno né una fase di acquisizione o bolla (ad esempio messa a fuoco, sfocatura e invio di eventi). Alcuni eventi che si propagano in alcuni browser non si propagano in altri.
  5. Gli elementi DOM che rispondono agli eventi hanno un gestore di eventi. Può essere impostato per ascoltare eventi particolari e chiamare una funzione listener quando quell'evento raggiunge l'elemento, durante l'acquisizione, bubbling o se l'elemento è un target di evento.
  6. Gli ascoltatori possono annullare la propagazione, ad es. un evento click su un arco all'interno di un link può annullare la propagazione in modo che il collegamento non ottiene il clic

luce di quanto sopra, si tratta di un'impossibilità pratica di "acquisire tutti gli eventi" utilizzando il Events API. Richiederebbe stabilire un listener per ogni tipo di evento su ogni elemento ed essere impossibile catturare eventi personalizzati perché devi conoscerli per impostare un listener appropriato.

immagino che ci sarebbe bisogno di essere un prototipazione di dispatchEvent o qualcosa

dispatchEvent è un metodo di un'istanza evento, non è specificato di essere un costruttore (non v'è alcun obbligo per lo avere un metodo interno [[Construct]]) quindi non è pratico da usare come tale. I browser non sono tenuti ad implementare l'ereditarietà del prototipo per gli oggetti host (sebbene la maggior parte lo faccia), e i dettagli di implementazione degli oggetti e dei metodi host sono in gran parte nascosti, quindi questa non è un'opzione.

Si potrebbe provare a estendere l'API di eventi, ma in realtà è should not mess with host objects.

Sembra che tu sia preoccupato per gli elementi aggiunti dinamicamente. Esiste una strategia chiamata "event delegation", dove si elaborano gli eventi che è necessario ascoltare, quindi impostare i listener il più vicino possibile agli obiettivi degli eventi su un elemento che non cambia (ad esempio un elemento di tabella se si aggiunge e rimuovere le righe della tabella o un contenitore div per altri elementi) per i tipi di eventi specifici a cui è necessario rispondere.

È anche possibile avere le funzioni che modificano gli eventi personalizzati di invio DOM per aggiungere listener o altro.

1

Se si desidera veramente eseguire questa operazione, è possibile ignorare lo addEventListener per tenere traccia degli eventi registrati e attivati.

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

}()); 

Tuttavia, non vi sono ragioni innumerevoli, non per fare questo, non ultimo il fatto che si eseguire rapidamente la memoria durante la registrazione migliaia di eventi come movimenti del mouse. Ciò inoltre non catturerà i listener di eventi impostati in modi come elt.onclick. Né naturalmente catturerà gli ascoltatori impostati tramite la vecchia API IE attachEvent. La cosa più importante, non ti aiuterà con gli eventi generati e ascoltati internamente, come un clic del mouse su una casella di controllo. (Una soluzione completa richiederebbe anche la manipolazione removeEventListener.)

Potete anche ignorare createEvent e dispatch in modo simile, ma ancora una volta, che cattura solo gli eventi che vengono esplicitamente creati o spediti nel codice JS.

Se vuoi davvero fare ciò che sembri voler, suppongo che devi biforcarti Chrome.

Problemi correlati