Dodavanje event handlera na nove elemente u JavaScriptu

Neka imamo listu ul i dugme:

html<ul>
  <li>stavka</li>
  <li>stavka</li>
  <li>stavka</li>
  <li>stavka</li>
  <li>stavka</li>
</ul>

<button>dodaj</button>

Hvatamo naše elemente u odgovarajuće promenljive:

javascriptlet button = document.querySelector('button');
let list   = document.querySelector('ul');
let items  = list.querySelectorAll('li');

Učinimo da na klik bilo koje li joj se na kraj doda uzvičnik:

javascriptfor (let item of items) {
  item.addEventListener('click', function() {
    this.textContent = this.textContent + '!';
  });
}

Hajde sada da učinimo da na pritisak na dugme na kraj liste doda nova li:

javascriptbutton.addEventListener('click', function() {
  let item = document.createElement('li');
  item.textContent = 'stavka';
  list.appendChild(item);
});

Međutim, dobićemo problem: klik na novu dodatu li neće dovesti do dodavanja uzvičnika na kraj. Stvar je u tome što dodajemo handler klika samo na one li koje su postojale na početku, ali ne na nove.

Ispravimo problem, dodavši na novu li handler klika:

javascriptbutton.addEventListener('click', function() {
  let item = document.createElement('li');
  item.textContent = 'stavka';
  
  item.addEventListener('click', function() { // handler klika
    this.textContent = this.textContent + '!';
  });
  
  list.appendChild(item);
});

Međutim, sada se kod funkcije-handlera duplira na dva mesta - za prvobitno postojeće li i za nove. Ispravimo ovo, izdvojivši ga u posebnu funkciju:

javascriptfunction handler() {
  this.textContent = this.textContent + '!';
}

Iskoristimo našu funkciju da izbegnemo dupliranje koda:

javascriptfor (let item of items) {
  item.addEventListener('click', handler);
}

button.addEventListener('click', function() {
  let item = document.createElement('li');
  item.textContent = 'stavka';
  
  item.addEventListener('click', handler);
  
  list.appendChild(item);
});

Zadatak je u suštini rešen i izbegli smo dupliranje koda funkcije-handlera. Međutim, dodavati event handlere i dalje moramo na dva mesta: i u petlji za postojeće li, i na klik dugmeta. U sledećoj lekciji ćemo razmotriti način da se rešimo ovog neudobstva.