Dowiesz się co to jest event propagation, event bubbling, do czego służy oraz jakie stoją za tym pułapki
Odpal konsolę (F12) i zerknij na ten przykład:
Dodałem nasłuchiwanie zdarzenie „click” do każdego elementu
Po kliknieciu w przycisk w konsoli wyświetli się
To co widzisz w konsoli, znane jest jako event bubbling, czyli obsługa kolejności wywołania zdarzenia w przodkach elementu, jest to kawalek mechanizmu zwanego, event propagation.
Brzmi skomplikowanie, ale takie nie jest.
Event propagation, daje nam możliwosć złapania zdarzenia niekoniecznie na poziomie w którym ono nastapiło. Np Mamy formularz, klikamy guzik submit, i chcemy wyslac caly formularz, a nie treść buttona.
<form onsubmit=”zrob cos”>
<input/>
<input/>
<button type=”submit”>wyslij</button>
</form>
Event został stworzony w button, jest propagowany do form i tam obsługiwany .
Obrazek w którym możemy zobaczyc jak to dziala znajdziemy tutaj
Mechanizm został stworzony w celu optymalizacji, by nie musieć tworzyc wielkiej ilości eventów, a tylko jeden.
Wewnarz zdarzenia eventConsole możemy się odwolać:
przez this do elementu który własnie obsługuje zdarzenie, lub przez event.target do elementu który spowodowal zdarzenie.
Proste i użyteczne, i można by bylo na tym skończyc, gdyby nie to, że czasem nie chcemy takiego zachowania.
Np mamy rozwijane menu/modal które chcemy zwinać w momęcie klikniecia gdzieś poza nim.
Ogólnie robi się to w taki sposób, że do elementu body dodajemy event listener, który zamyka to menu/modal.
Przykład znajduje się tutaj:
Jednak po kliknieciu w buton nic się nie dzieje! Gdzie jest blad?
Spójrz w konsole, problem w tym że się dzieje i to za duzo. Event click został wywolany na przycisku menu, a potem spopagowany do elementu body. Jak sobie z tym poradzic?
Otóż standard DOM definiuje metodę event.stopPropagation. Która przerywa propagacje. Więc jedyne co trzeba zrobić, to dodać do event lisinera buttona, wywolanie metody event.stopPropagation()
Można zobaczyc to tutaj:
Wszystko dziala!
…a nie, jednak nie, kliknijcie w dowolny link w menu, spowoduje zamkniecie menu.
Zastanów się co nalezy zrobic, by menu nie zamykalo się, po kliknieciu w nie, a potem zaimplementuj to!
Powodzenia
Na koniec fajne rzeczy które warto wiedziec.
Event posiada nastepujace metody:
- event.target => referencja do obiektu który powoduje zdarzenie
- event.currentTarget => to samo co this
- event.eventPhase =>zwraca stan event flow
- CAPTURING_PHASE
- BUBBLING_PHASE
- AT_TARGET
Przyklad :
Zdarzenia które nie sa propagowane w gore:
- blur
- focus
- load
- unload
Zdarzenia które powoduja natywne przerwanie propagacji:
- click na formularzu powodujacy submit
- click na linku (element a)
powyższe zdarzenia powoduja przeładowanie strony, jeżeli chcemy by jednak event propagation nastapił musimy wywołać event.preventDefault.