0Pricing
JavaScript Academy · Lekcja

Fazy przechwytywania i propagacji

Proszę zrozumieć, jak zdarzenia przemieszczają się przez DOM.

Fazy przechwytywania i propagacji to bezpłatna lekcja JavaScript Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej JavaScript Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs JavaScript Academy zawiera 4 lekcji w sumie.

Dwie fazy przepływu przez DOM

Gdy klikają Państwo element, zdarzenie nie jest wywoływane wyłącznie na tym elemencie. Przechodzi ono przez drzewo DOM w dwóch fazach: fazie przechwytywania (z góry na dół, od document do elementu docelowego) oraz fazie propagacji w górę (z dołu do góry, od elementu docelowego z powrotem do document).

<div id="outer">
  <button id="inner">Click</button>
</div>

Domyślnie: propagacja w górę

Domyślnie addEventListener nasłuchuje podczas fazy propagacji w górę. Kliknięcie wewnętrznego przycisku najpierw uruchamia jego handler, następnie handler jego elementu nadrzędnego, potem handler elementu nadrzędnego wyższego poziomu i tak dalej, aż do document.

inner.addEventListener("click", () => console.log("inner"));
outer.addEventListener("click", () => console.log("outer"));
// Click inner -> logs: "inner" then "outer"

Włączanie przechwytywania

Aby nasłuchiwać zamiast tego podczas fazy przechwytywania, należy przekazać trzeci argument o wartości true (lub { capture: true }). Handlery przechwytywania są uruchamiane z góry na dół, przed handlerami propagacji w górę.

outer.addEventListener("click", () => console.log("outer capture"), true);
inner.addEventListener("click", () => console.log("inner bubble"));
// Click inner -> "outer capture" then "inner bubble"

Pełna kolejność

Dla kliknięcia elementu #inner z handlerami w obu fazach kolejność jest następująca: faza przechwytywania od góry do dołu, następnie element docelowy, a potem faza propagacji w górę od dołu do góry.

  • przechwytywanie na document
  • przechwytywanie na outer
  • inner (element docelowy)
  • propagacja w górę na outer
  • propagacja w górę na document

event.target a event.currentTarget

event.target to element, który rzeczywiście wywołał zdarzenie, czyli miejsce kliknięcia. event.currentTarget to element, którego listener jest obecnie wykonywany. W handlerze elementu nadrzędnego obsługującym propagację w górę te wartości są różne.

outer.addEventListener("click", (e) => {
  console.log(e.target.id);        // "inner" - where click occurred
  console.log(e.currentTarget.id); // "outer" - listener owner
});

Zatrzymywanie propagacji

event.stopPropagation() zatrzymuje dalszą drogę zdarzenia: nie przejdzie ono do następnego elementu w bieżącej fazie. Handlery elementów nadrzędnych znajdujących się wyżej w drzewie nie zostaną uruchomione.

inner.addEventListener("click", (e) => {
  e.stopPropagation();
  console.log("handled here only");
});
outer.addEventListener("click", () => console.log("never runs"));

stopImmediatePropagation

stopPropagation() nadal pozwala działać innym listenerom na tym samym elemencie. Aby zablokować również sąsiednie listenery na tym elemencie, należy użyć event.stopImmediatePropagation().

inner.addEventListener("click", (e) => {
  e.stopImmediatePropagation();
  console.log("first only");
});
inner.addEventListener("click", () => console.log("blocked"));

preventDefault działa inaczej

Nie należy mylić preventDefault() z stopPropagation(). preventDefault() anuluje domyślną akcję przeglądarki (przejście za odnośnikiem, wysłanie formularza), ale NIE zatrzymuje propagacji zdarzenia w górę.

link.addEventListener("click", (e) => {
  e.preventDefault();  // do not navigate
  // event still bubbles to parents
});

Dlaczego przechwytywanie jest rzadkie

Większość kodu korzysta z propagacji w górę, ponieważ odpowiada to intuicji: najpierw reaguje konkretny element, a następnie informację o zdarzeniu otrzymują kontenery. Przechwytywanie jest przydatne, gdy element nadrzędny musi przechwycić lub odrzucić zdarzenie, zanim zobaczą je elementy potomne.

Sprawdzanie fazy

event.eventPhase informuje, która faza jest aktywna: 1 — przechwytywanie, 2 — cel, 3 — propagacja w górę. Jest to rzadko potrzebne, ale pomaga podczas debugowania złożonych łańcuchów listenerów.

el.addEventListener("click", (e) => {
  console.log(e.eventPhase); // 1, 2, or 3
}, true);

Nie wszystkie zdarzenia propagują się w górę

Większość zdarzeń interfejsu użytkownika (click, input, keydown) propaguje się w górę. Kilka z nich domyślnie tego nie robi, na przykład focus, blur i mouseenter. W ich przypadku należy użyć wariantów propagujących się w górę (focusin, focusout) albo fazy przechwytywania.

Szybki test

Proszę sprawdzić rozumienie faz zdarzeń.

Podsumowanie

Zdarzenia najpierw przechodzą przez fazę przechwytywania (w dół), a następnie przez fazę propagacji w górę (w górę). Listenery domyślnie korzystają z propagacji w górę; aby włączyć przechwytywanie, należy przekazać true. e.target to źródło zdarzenia, a e.currentTarget to element, do którego należy listener. stopPropagation() zatrzymuje propagację, a preventDefault() anuluje domyślne akcje. Te dwie fazy stanowią podstawę delegowania zdarzeń.

Często zadawane pytania

Czy lekcja „Fazy przechwytywania i propagacji” jest bezpłatna?

Tak — pełny tekst „Fazy przechwytywania i propagacji” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu JavaScript Academy, przejdź na CoddyKit PRO. Kurs JavaScript Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Fazy przechwytywania i propagacji”?

Proszę zrozumieć, jak zdarzenia przemieszczają się przez DOM. Ćwiczysz JavaScript Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć JavaScript Academy?

Nie wymagamy żadnego doświadczenia. JavaScript Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.

Ile czasu zajmuje lekcja „Fazy przechwytywania i propagacji”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji JavaScript Academy?

Tak. Każda lekcja JavaScript Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Fazy przechwytywania i propagacji
  2. Wzorzec delegowania zdarzeń
  3. Dynamiczne listy z delegowaniem zdarzeń
  4. Zdarzenia niestandardowe
← Powrót do JavaScript Academy