7

In jQuery, è possibile effettuare le seguenti operazioni:Chiusura evento delegazione - listener di eventi sul genitore DOM che copre i bambini/discendenti di una data classe

$('#j_unoffered').on('click', '.icon_del', function() {... 

Questo pone un gestore sull'elemento j_unoffered che gli incendi eventuali discendente elemento con classe icon_del viene cliccato. Si applica, inoltre, a qualsiasi elemento icon_del creato successivamente.

Posso ottenere questo funzionamento in Chiusura in cui il clic è sull'elemento stesso.

goog.events.listen(
    goog.dom.getElement('j_unoffered'), 
    goog.events.EventType.CLICK, 
    function(e) {... 

Come posso specificare un obiettivo evento principale in chiusura che lavora per i suoi bambini/discendenti nello stesso modo come l'esempio jQuery?

Suppongo di dover usare lo setParentEventTarget in qualche modo, ma non sono sicuro di come implementarlo per gli eventi DOM. La maggior parte della documentazione che ho trovato riguarda gli eventi di spedizione personalizzati.

- AGGIORNAMENTO -

Mi chiedo se c'è qualcosa di sbagliato in questo piuttosto semplice soluzione:

goog.events.listen(
    goog.dom.getElement('j_unoffered'), 
    goog.events.EventType.CLICK, 
    function(e) { 
     if (e.target.className.indexOf('icon_del') !== -1) {... 

lascia ancora this legata al genitore, ma e.target permette un lavoro- in giro. Il quinto argomento in listen (opt_handler) consente di associare this a qualcos'altro, quindi immagino che sia anche una strada.

risposta

5

non so su tale possibilità anche, quindi suggerisco altro pezzo di codice:

var addHandler = function(containerSelector, eventType, nestSelector, handler) { 
    var parent = goog.isString(containerSelector) ? 
       document.querySelector(containerSelector) : 
       containerSelector; 

    return goog.events.listen(
     parent, 
     eventType, 
     function(e) { 

      var children = parent.querySelectorAll(nestSelector); 
      var needChild = goog.array.find(children, function(child) { 
       return goog.dom.contains(child, e.target); 
      }); 

      if (needChild) 
       handler.call(needChild, e);     

     }); 
}); 

Usage:

addHandler('#elem', goog.events.EventType.CLICK, '.sub-class', function(e) { 
    console.log(e.target); 
}); 

Aggiornamento:

Se si intende utilizzare questo e.target.className.indexOf('icon_del') ci sarà la possibilità di perdere gli eventi giusti. Considerare un contenitore div con id = container, ha un paio di div con classe innerContainer e ognuno di essi contiene un paio di div con classe = finalDiv. E considera che aggiungerai il gestore di eventi con il tuo codice sopra, che controllerà e.target per la classe innerContainer.Il problema si verifica quando l'utente fa clic su finalDiv per chiamare il gestore, ma il target dell'evento sarà finalDiv, che non è innerContainer, ma da esso contenuto. Il tuo codice mancherà, ma non dovrebbe. Il mio codice controlla se e.target ha una classe nidificata o contenuta da essa, quindi non perderai questi eventi.

opt_handler non può davvero aiutarti, perché potrebbero esserci molti elementi nidificati che vuoi modificare (quale di loro passerai qui? Forse tutto, ma non così utile, puoi ottenerli nel gestore eventi ogni volta che vuoi), inoltre possono essere aggiunti dinamicamente dopo, quindi quando aggiungi il gestore non puoi conoscerli.

In conclusione, penso che fare un simile lavoro in un gestore di eventi sia giustificato e più efficiente.

+0

+1 per un buon inizio, ma sono sicuro che lo staff di Google deve averlo riscontrato prima, quindi sono riluttante a reinventare la ruota. Vedi anche il mio aggiornamento. – Nick

+0

Grazie! Vedi la mia risposta aggiornata. – Tony

+0

@Nick vediamo qualche demo: http://jsfiddle.net/g3Vj6/1/ (ho dovuto cambiare un po 'il codice, perché non c'è chiusura in jsfiddle, ma l'approccio è lo stesso). Prova a fare clic sugli oggetti defferenti e guarda cosa succede. Immagino che il secondo approccio sia più corretto. – Tony

3

Cosa si fa riferimento si chiama eventdelegation

E seems che questo non è possibile (out of the box) con Google chiusura biblioteca; Quindi la mia raccomandazione è di usare jQuery o un'altra libreria di gestione eventi simile che offre questa funzionalità. Se ciò non è possibile o se si desidera fare a mano, ecco un possibile approccio (Nota: questo non è per l'uso in produzione)

var delegateClick = function(containerId, childrenClass, handler){ 
    goog.events.listen(goog.dom.getElement(containerId), goog.events.EventType.CLICK, function(event){ 
    var target = event.target; 
    //console.log(event); 
    while(target){ 
     if (target.className && target.className.split(" ").indexOf(childrenClass)!== -1) { 
     break; 
     } 
     target = target.parentNode; 
    } 
    if(target){ 
     //handle event if still have target 
     handler.call(target, event); 
    } 
    }); 
} 
//then use it, try this here: http://closure-library.googlecode.com/git/closure/goog/demos/index.html 
//..select the nav context 
delegateClick('demo-list' ,'goog-tree-icon', function(event){console.log(event);}) 

Ecco un'analisi più approfondita di eventdelegation

Anche in questo caso, è dovrebbe utilizzare una libreria provata per questo, qui ci sono alcune opzioni: jQuery, Zepto, Bean

+0

Grazie per la terminologia 'delegazione evento'. Lo uso; Non riuscivo proprio a ricordare come si chiamava :) Penso che sia un lungo inchino suggerire che Closure non è una "biblioteca provata". +1 per una buona partenza, però. Vedi anche il mio aggiornamento. – Nick

+0

@Nick Stavo suggerendo una libreria comprovata (qualsiasi) per la gestione/delegazione degli eventi, al contrario di fare la tua. Non stavo suggerendo che Closure non è una buona lib. Saluti :) – MarianCJC

+0

Ciao di nuovo. Perché dici "questo non è per uso produttivo"? – Nick

Problemi correlati