Uute elementidele sündmuste käitlejate lisamine JavaScriptis

Oletame, et meil on loend ul ja nupp:

html<ul>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
</ul>

<button>add</button>

Hankige meie elemendid vastavatesse muutujatesse:

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

Teeme nii, et mis tahes li-ile klõpsamine lisaks sellele lõppu hüüumärgi:

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

Teeme nüüd nii, et nupu vajutamisel lisatakse loendi lõppu uus li:

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

Meil tekib aga probleem: klõps uuele lisatud li-le ei too kaasa hüüumärgi lisamist lõppu. Asi on selles, et me lisame klõpsu käitleja ainult nendele li-dele, mis eksisteerisid algselt, kuid mitte uutele.

Parandame probleemi, lisades uuele li-le klõpsu käitleja:

javascriptbutton.addEventListener('click', function() {
  let item = document.createElement('li');
  item.textContent = 'item';
  
  item.addEventListener('click', function() { // klõpsu käitleja
    this.textContent = this.textContent + '!';
  });
  
  list.appendChild(item);
});

Siiski nüüd on funktsiooni-käitleja kood dubleeritud kahes kohas - algselt olemasolevate li-de jaoks ja uute jaoks. Parandame selle, viies selle eraldi funktsiooni:

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

Kasutame meie funktsiooni, et vältida koodi dubleerimist:

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

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

Ülesanne on üldiselt lahendatud ja me oleme vältinud funktsiooni-käitleja koodi dubleerimist. Siiski, sündmuste käitlejate lisamine tuleb meil ikka kahes kohas: nii tsüklis olemasolevate li-de jaoks, kui ka nupu klõpsamisel. Järgmises õppetükis vaatleme võimalust, kuidas sellest ebamugavusest lahti saada.