, , ,

Event delegation w JS

Eventy w JavaScript mogą być propagowane, co oznacza, że zdarzenie wywołane na elemencie potomnym przechodzi przez wszystkich rodziców. Zastosowanie wzorca Event Delegation polega na obsłudze zdarzenia w elemencie nadrzędnym. Jest przydatny, gdy mamy wiele podobnych elementów, a ich obsługa nie różni się w znacznym stopniu. To, co jest ważne w tym wzorcu, to propagacja zdarzeń oraz cel (target) zdarzenia. Poniżej przedstawiono kilka przykładów użycia.

Prosty przykład


Dobrym przykładem ilustrującym zastosowanie wzorca Event Delegation będzie menu, gdzie chcemy niestandardowo obsłużyć nawigację.

Struktura HTML będzie wyglądała mniej więcej tak:

<div id="menu">
  <button data-page="home">Home</button>
  <button data-page="about">About</button>
  <button data-page="contact">Contact</button>
</div>Code language: HTML, XML (xml)

Do obsługi nawigacji moglibyśmy tworzyć listenery na kliknięcia w poszczególne elementy button, ale dzięki wzorcowi Event Delegation obsłużymy kliknięcia w buttony za pomocą jednego listenera, który podepniemy pod div #menu

document.getElementById('menu').addEventListener('click', (event) => {
  const page = event.target.dataset.page;
  if (page) {
    // obsługa nawigacji
    console.log(`Navigate to ${navigation}`);
  }
});Code language: JavaScript (javascript)

Oczywiście, jeśli mielibyśmy więcej menu w różnych miejscach na stronie i obsługiwaliśmy je w ten sam sposób, nic nie stoi na przeszkodzie, abyśmy obsłużyli nawigację nasłuchując na elemencie

Określanie Celu (Target)

Weźmy teraz na tapetę bardziej skomplikowany przykład użycia wzorca Event Delegation. Będzie to podświetlenie wiersza w tabeli po kliknięciu, niezależnie czy klikniemy w komórkę czy w sam wiersz. Dodatkowo chcemy wykluczyć z tej logiki podświetlanie nagłówków tabeli.

HTML tabeli:

<table id="table">
  <thead>
    <tr>
      <th>Kolumna 1</th>
      <th>Kolumna 2</th>
      <th>Kolumna 3</th>
      <th>Kolumna 4</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Wiersz 1, Kolumna 1</td>
      <td>Wiersz 1, Kolumna 2</td>
      <td>Wiersz 1, Kolumna 3</td>
      <td>Wiersz 1, Kolumna 4</td>
    </tr>
    ....
  </tbody>
</table>Code language: HTML, XML (xml)

W JS będziemy nasłuchiwać na elemencie #table

document.getElementById('table').addEventListener('click', function(event) {
  let row = event.target;

  while (row.tagName !== this) {
    if (row.tagName === 'TR') {
      if (row.parentElement.tagName === 'TBODY') {

        // obsługa podświetlenia wiersza
        console.log('Highlight row', row);
      }

      return;
    }
    
    row = row.parentElement;
  }
});
Code language: JavaScript (javascript)

Za pomocą pętli while sprawdzamy, czy zmienna row to element TR. Jeśli tak, to sprawdzamy, czy row znajduje się w TBODY. Jeśli oba warunki są spełnione, możemy podświetlić wiersz i zakończyć funkcję. Jeśli row znajdowałby się w THEAD, wtedy nie obsłużymy podświetlenia i zakończymy funkcję.

W ten sposób możemy określić odpowiedni cel (target) i wykonać na nim potrzebne operacje.

Podsumowanie

Event Delegation jest skutecznym narzędziem, gdy musimy obsłużyć wiele elementów w ten sam sposób lub gdy elementy w drzewie DOM są usuwane lub dodawane, a my musimy reagować na ich zdarzenia. Jest wydajny, ponieważ zamiast nasłuchiwać wielu elementów, nasłuchujemy tylko na jednym.

Musimy pamiętać, że by ten wzorzec działał, zdarzenie musi być propagowane aż do elementu, w którym zawarta jest obsługa. Oznacza to, że nie możemy wcześniej wywołać metody event.stopPropagation(). Czasami mogą być też potrzebne dodatkowe działania do ustalenia odpowiedniego celu (targetu).

Nasza pasja do technologii nie kończy się na dostarczaniu wnikliwych treści poprzez ten blog. Zapraszamy po więcej tajników specjalistycznej wiedzy dla entuzjastów takich jak Ty.

Tematy

animacje animate Attribute inheritance Block Theme Branża IT bug Code Comments CSS CSS Flexbox developer tools Doc Blocks dostępność www Edge Edge computing Editor Flex Gap FSE Full Site Editing GIT GIT Submodules Gutenberg HTTP HTTP/2 HTTP/3 IT JS Memcached Optimization plik SVG Praca praca w IT Rozmowy o WordPress strony www SVG Text-overflow theme.json v-model Vue.js wcag web accessibility Web development webkit line clamp Wordpress wp postmeta api wp transient