Naujų elementų apdorojimo programų pridėjimas JavaScript

Tarkime, kad turime ul sąrašą ir mygtuką:

html<ul>
  <li>elementas</li>
  <li>elementas</li>
  <li>elementas</li>
  <li>elementas</li>
  <li>elementas</li>
</ul>

<button>pridėti</button>

Gaukime savo elementus į atitinkamus kintamuosius:

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

Padarykime taip, kad paspaudus bet kurį li prie jo galo būtų pridėtas šauktukas:

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

Dabar padarykime taip, kad paspaudus mygtuką į sąrašo galą būtų pridėtas naujas li:

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

Tačiau mes susidursime su problema: paspaudimas į naujai pridėtą li nesukels šauktuko pridėjimo prie galo. Esmė ta, kad mes pridedame paspaudimo apdorojimo programą tik tiems li, kurie egzistavo iš pradžių, bet ne naujiems.

Išspręskime problemą, pridėdami prie naujo li paspaudimo apdorojimo programą:

javascriptbutton.addEventListener('click', function() {
  let item = document.createElement('li');
  item.textContent = 'elementas';
  
  item.addEventListener('click', function() { // paspaudimo apdorojimo programa
    this.textContent = this.textContent + '!';
  });
  
  list.appendChild(item);
});

Tačiau dabar apdorojimo programos funkcijos kodas dubliuojasi dviejose vietose - iš pradžių egzistuojantiems li ir naujiems. Išspręskime tai, išskirdami jį į atskirą funkciją:

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

Naudokimės mūsų funkcija, kad išvengtume kodo dubliavimo:

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

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

Iš esmės problema išspręsta ir išvengėme apdorojimo programos funkcijos kodo dubliavimo. Tačiau, pridėti įvykių apdorojimo programas mums vis tiek tenka dviejose vietose: ir cikle egzistuojantiems li, ir paspaudus mygtuką. Kitoje pamokoje mes išnagrinėsime būdą, kaip atsikratyti šio nepatogumo.