7

w jQuery, można wykonać następujące czynności:Zamknięcie wydarzenie delegacja - detektor zdarzeń na DOM rodzica, który obejmuje dzieci/potomków danej klasy

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

Stawia jeden obsługi na elemencie j_unoffered odpala jeśli każdy potomek element z klasą icon_del został kliknięty. Dotyczy to również później utworzonego elementu.

Mogę to sprawić, że działa dobrze w Zamknięciu, gdzie kliknięcie znajduje się na samym elemencie.

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

Jak mogę określić cel nadrzędny zdarzeń zamknięciem, który pracuje dla swoich dzieci/potomków w taki sam sposób jak w przykładzie jQuery?

W pewnym sensie potrzebuję użyć setParentEventTarget w jakiś sposób, ale nie jestem pewien, jak zaimplementować go dla zdarzeń DOM. Większość dokumentacji, którą znalazłem, dotyczy niestandardowych wydarzeń wysyłkowych.

- AKTUALIZACJA -

Zastanawiam się, czy jest coś złego w tym dość proste rozwiązanie:

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

nadal pozostawia this związany z rodzicem, ale e.target umożliwia pracą na około. Piąty argument w listen (opt_handler) pozwala ci związać this z czymś innym, więc myślę, że to też jest droga.

Odpowiedz

5

nie wiem o takiej możliwości też, więc proponuję inny fragment kodu:

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

     }); 
}); 

Zastosowanie:

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

Aktualizacja:

Jeśli będziesz używać tej e.target.className.indexOf('icon_del') tam będzie możliwość przegapić odpowiednie wydarzenia. Rozważmy div kontenera o id = container, ma on parę elementów div z klasą innerContainer, a każda z nich zawiera parę elementów div o klasie = finalDiv. Zastanów się nad dodaniem obsługi zdarzeń z powyższym kodem, który sprawdzi klasę e.target dla klasy innerContainer.Problem polega na tym, że użytkownik kliknie finalDiv zostanie wywołany twój handler, ale docelowym zdarzeniem będzie finalDiv, który nie jest innerContainer, ale jest przez niego zawarty. Twój kod go ominie, ale nie powinien. Mój kod sprawdza, czy e.target ma klasę zagnieżdżoną lub zawartą w niej, więc nie przegapisz takich zdarzeń.

opt_handler tak naprawdę nie może ci pomóc, ponieważ może istnieć wiele elementów zagnieżdżonych, które chcesz hanlde (które z nich możesz przekazać tutaj - być może wszystkie, ale nie tak pomocne, możesz je uzyskać w programie obsługi zdarzeń za każdym razem, gdy chcieć), ponadto można je dodawać dynamicznie po, więc po dodaniu obsługi nie można o nich wiedzieć.

Podsumowując, myślę, że wykonywanie takiej pracy w programie obsługi zdarzeń jest uzasadnione i najbardziej wydajne.

+0

+1 na dobry początek, ale jestem przekonany, że pracownicy Google musieli to wcześniej zauważyć, więc niechętnie wymyślam nowe koło. Zobacz także moją aktualizację. – Nick

+0

Dzięki! Zobacz moją zaktualizowaną odpowiedź. – Tony

+0

@Nick, zobaczmy demo: http://jsfiddle.net/g3Vj6/1/ (Musiałem trochę zmienić kod, ponieważ nie ma zamknięcia w jsfiddle, ale podejście jest takie samo). Spróbuj kliknąć różne elementy i zobacz, co się stanie. Sądzę, że drugie podejście jest bardziej poprawne. – Tony

3

Co masz na myśli nazywa eventdelegation

It seems, że to nie jest możliwe (po wyjęciu z pudełka) z zamknięciem biblioteki Google; Tak więc moim zaleceniem jest użycie jQuery lub innej podobnej biblioteki obsługi zdarzeń, która oferuje tę funkcjonalność. Jeśli nie jest to możliwe lub jeśli chcesz zrobić to ręcznie tutaj jest jednym z możliwych rozwiązań (UWAGA: to nie jest do użytku produkcyjnego)

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

Oto dokładniejsze analizy z eventdelegation

Ponownie, powinni stosować sprawdzoną bibliotekę dla tego, oto kilka opcji: jQuery, Zepto, Bean

+0

Dzięki za terminologię "delegowania zdarzeń". Używam tego; Nie mogłem sobie przypomnieć, jak to się nazywało. Myślę, że to długi łuk sugerujący, że Zamknięcie nie jest "sprawdzoną biblioteką". +1 dla dobrego startu. Zobacz także moją aktualizację. – Nick

+0

@Nick Sugerowałem sprawdzoną bibliotekę (dowolną) do obsługi/delegowania zdarzeń, a nie do własnej. Nie sugerowałem, że zamknięcie nie jest dobrą biblioteką. Pozdrawiam :) – MarianCJC

+0

Witaj ponownie. Dlaczego mówisz "to nie jest do użytku produkcyjnego"? – Nick

Powiązane problemy