Dodeljevanje obravnavalcev novim elementom v JavaScript

Recimo, da imamo seznam ul in gumb:

html<ul>
  <li>element</li>
  <li>element</li>
  <li>element</li>
  <li>element</li>
  <li>element</li>
</ul>

<button>dodaj</button>

Pridobimo naše elemente v ustrezne spremenljivke:

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

Naredimo tako, da se ob kliku na katero koli li doda klicaj na konec:

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

Sedaj naredimo tako, da se ob pritisku na gumb na konec seznama doda nov li:

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

Vendar bomo naleteli na težavo: klik na novo dodano li ne bo povzročil dodajanja klicaja na konec. Bistvo je v tem, da dodajamo obravnavalec klika samo na tiste li, ki so obstajali sprva, ne pa na nove.

Popravimo težavo tako, da na novo li dodelimo obravnavalec klika:

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

Vendar se zdaj koda funkcije-obravnavalca podvaja na dveh mestih - za prvotno obstoječe li in za nove. Popravimo to tako, da jo izločimo v ločeno funkcijo:

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

Uporabimo našo funkcijo, da se izognemo podvajanju kode:

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

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

Naloga je na splošno rešena in izognili smo se podvajanju kode funkcije-obravnavalca. Vendar moramo še vedno dodeljevati obravnavalce dogodkov na dveh mestih: tako v zanki za obstoječe li, kot ob kliku na gumb. V naslednji lekciji bomo obravnavali način, kako se znebiti te neugodnosti.