Jak podpinać zdarzenia - event delegation

Podpinanie zdarzeń warto zaplanować, aby później nie było konfliktów, jeśli aplikacje rozbudowujemy.

Najlepszym sposobem na unikniecie problemów jest użycie 'event delegation' - delegacja zdarzeń tak dziwnie brzmi.

Wybieramy główny element DOM, najlepiej aby to był kontener który zawiera wszystkie elementy jakiejś funkcjonalności, w naszym przykładzie np.: będą to wiadomości news. Pod ten element podpinamy event click(), warto ustawić takiemu elementowi id.

<div id="news">
  <h3>News <a href="#" class="more">more</a></h3>
  <ul>
    <li><a href="#" class="open">News Title 1</a></li>
    <li><a href="#" class="open">News Title 2</a></li>
  </ul>
</div>

pod #news podpinamy zdarzenie click:

$('#news').click (function(e) {
  var self = e.target;
});

Wykorzystując bąbelkowanie zdarzeń, możemy sprawdzić który element został kliknięty:

$('#news').click (function(e) {
  var self = e.target, classes;
  switch (self.tagName) {
    case 'A':
      classes = ' ' + self.className + ' ';
      if (~classes.indexOf (' more ')) {
        // link more
        return false;
      } else if (~classes.indexOf (' open ')) {
        // link open
        return false;
      }
    break;

    case 'INPUT':
      ...
    break;
  }
});

Możemy użyć metody .delegate() z jQuery, ma podobne działanie, choć jest wolniejsze.

Zobacz event delegation w akcji na JSFiddle.net

Zalety takiego rozwiązania: 

  1. podpinamy jeden raz zdarzenie,
  2. w przypadku, gdy używany ajax'a możemy zastępować dynamicznie cały element pod który jest podpięte zdarzenie, (w naszym przykładzie pod #news), a zdarzenia będą nadal działały na elementach wewnątrz,
  3. metoda jest dużo szybsza niż .live() .delegate().