Direct vs. Delegated-jQuery.on()

Staram się zrozumieć tę szczególną różnicę międzybezpośrednimi idelegowanymi manipulatorami zdarzeń przy użyciu jQuery .on () metoda . W szczególności ostatnie zdanie w tym akapicie:

Gdy podano selector, Obsługa zdarzenia jest określana jakodelegated . Procedura obsługi nie jest wywoływana, gdy zdarzenie wystąpi bezpośrednio na powiązanym elemencie, ale tylko dla potomków (elementów wewnętrznych), które pasują do selektora. jQuery bubbles Zdarzenie od obiektu docelowego zdarzenia do elementu, do którego dołączony jest moduł obsługi (tzn. element najbardziej wewnętrzny do elementu zewnętrznego) i uruchamia moduł obsługi dla dowolnych elementów wzdłuż tej ścieżki pasującej do selektora.

Co to znaczy "uruchamia obsługę dla dowolnych elementów"? Zrobiłem stronę testową , aby poeksperymentować z koncepcją. Jednak obie następujące konstrukcje prowadzą do tego samego zachowania: {]}

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

Lub

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

Może ktoś mógłby odnieść się do innego przykładu, aby wyjaśnić ten punkt? Dzięki.

Author: RPichioli, 2011-11-13

5 answers

Przypadek 1 (bezpośredni):

$("div#target span.green").on("click", function() {...});

== Hej! Chcę każdą rozpiętość.green inside div # target to listen up: when you get clicked on, do X.

Przypadek 2 (delegowany):

$("div#target").on("click", "span.green", function() {...});

== Hey, div#target! Gdy którykolwiek z elementów dziecka, które są " span.zielony " daj się kliknąć, zrób z nimi X.

Innymi słowy...

W przypadku 1, każdy z tych przęseł otrzymał indywidualnie instrukcje. Jeśli nowe przęsła zostaną utworzone, nie usłyszą instrukcji i nie odpowiada na kliknięcia. Każdy span jest bezpośrednio odpowiedzialny za swoje własne zdarzenia.

W przypadku 2 tylko kontener otrzymał instrukcję; jest on odpowiedzialny za Zauważenie kliknięć w imieniu jego elementów potomnych. Praca nad wyłapywaniem zdarzeń została przekazana . Oznacza to również, że instrukcja zostanie wykonana dla elementów potomnych, które zostaną utworzone w przyszłości.

 345
Author: N3dst4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 09:37:58

Pierwszy sposób, $("div#target span.green").on(), wiąże funkcję obsługi kliknięć bezpośrednio z zakresami pasującymi do selektora w momencie wykonania kodu. Oznacza to, że jeśli inne przęsła zostaną dodane później (lub zmienią ich klasę na dopasowaną), zostaną one pominięte i nie będą miały obsługi kliknięć. Oznacza to również, że jeśli później usuniesz" zieloną " klasę z jednego z zakresów, jej obsługa kliknięć będzie nadal działać - jQuery nie śledzi sposobu przypisania obsługi i sprawdza, czy selektor nadal zapałki.

Drugi sposób, $("div#target").on(), wiąże funkcję obsługi kliknięć z div(s), które pasują (ponownie, jest to w stosunku do tych, które pasują w tym momencie), ale gdy nastąpi kliknięcie gdzieś w div, funkcja obsługi zostanie uruchomiona tylko wtedy, gdy kliknięcie nastąpiło nie tylko w div, ale w elemencie potomnym pasującym do selektora w drugim parametrze do .on(), "span.zielony". W ten sposób nie ma znaczenia, kiedy te przęsła potomne zostały utworzone, kliknięcie na nich nadal uruchomi funkcję obsługi.

Więc w przypadku strony, która nie dodaje dynamicznie ani nie zmienia swojej zawartości, nie zauważysz różnicy między tymi dwiema metodami. Jeśli dynamicznie dodajesz dodatkowe elementy potomne, druga składnia oznacza, że nie musisz się martwić o przypisanie do nich programów obsługi kliknięć, ponieważ zrobiłeś to już raz na rodzicu.

 5
Author: nnnnnn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-13 11:03:55

Wyjaśnienie N3dst4 jest doskonałe. Na tej podstawie możemy założyć, że wszystkie elementy potomne znajdują się wewnątrz ciała, dlatego musimy używać tylko tego:

$('body').on('click', '.element', function(){
    alert('It works!')
});

Działa z wydarzeniem direct lub delegate.

 4
Author: Brynner Ferreira,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-25 16:42:17

Styczna do OP, ale koncepcja, która pomogła mi rozwikłać zamieszanie z tą cechą jest to, że powiązane elementy muszą być rodzicami wybranych elementów.

  • Bound odnosi się do tego, co pozostało z .on.
  • Selected odnosi się do drugiego argumentu .on().

Delegacja nie działa jak .find(), wybierając podzbiór powiązanych elementów. Selektor ma zastosowanie tylko do ścisłych elementów potomnych.

$("span.green").on("click", ...

Jest bardzo różne od

$("span").on("click", ".green", ...

W szczególności, aby uzyskać zalety podpowiedzi @N3dst4 z "elementami, które są tworzone w przyszłości", związany element musi być stałym rodzicem. Następnie wybrane dzieci mogą przychodzić i odchodzić.

EDIT

Lista kontrolna dlaczego delegowane .on nie działa

Trudne powody, dla których $('.bound').on('event', '.selected', some_function) mogą nie działać:

  1. element związany nie jest stałym . Został utworzony po wywołaniu .on()
  2. wybrany element nie jest właściwym dziecko elementu związanego. To ten sam element.
  3. wybrany element uniemożliwia bąbelkowanie zdarzenia do powiązanego elementu przez wywołanie .stopPropagation().

(pomijając mniej zawiłe powody, takie jak źle napisany selektor.)

 2
Author: Bob Stein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 11:48:06

I wro te post z porównaniem zdarzeń bezpośrednich i delegowanych. Porównuję czysty js, ale ma to samo znaczenie dla jquery, które tylko go enkapsuluje.

Wniosek jest taki, że delegowana obsługa zdarzeń jest dla dynamicznej struktury DOM, gdzie można tworzyć powiązane elementy podczas interakcji użytkownika ze stroną( nie ma potrzeby ponownego wiązania), a bezpośrednia obsługa zdarzeń jest dla statycznych elementów DOM, gdy wiemy, że struktura nie ulegnie zmianie.

Aby uzyskać więcej informacji i pełne porównanie - http://maciejsikora.com/standard-events-vs-event-delegation/

Używanie zawsze delegowanych programów obsługi, które jak widzę są obecnie bardzo modne, nie jest w porządku, wielu programistów używa go, ponieważ "powinno być używane", ale prawda jest taka, że bezpośrednie programy obsługi zdarzeń są lepsze w jakiejś sytuacji i wybór, Która metoda powinna być poparta wiedzą o różnicach.

 1
Author: Maciej Sikora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-13 10:21:09