Die aanheg van gebeurtenishanteerders op nuwe elemente in JavaScript

Kom ons sê ons het 'n ul lys en 'n knoppie:

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

<button>add</button>

Laat ons ons elemente in ooreenstemmende veranderlikes kry:

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

Laat ons dit so maak dat wanneer op enige li geklik word, 'n uitroepteken aan die einde daarvan gevoeg word:

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

Laat ons nou maak so dat wanneer die knoppie gedruk word, 'n nuwe li aan die einde van die lys gevoeg word:

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

Ons sal egter 'n probleem kry: 'n klik op die nuwe bygevoegde li sal nie lei tot die byvoeging van 'n uitroepteken aan die einde nie. Die feit is dat ons 'n klik-hanteerder slegs byvoeg vir daardie li-elemente wat aanvanklik bestaan het, maar nie vir nuwe eenhede nie.

Laat ons die probleem regstel deur 'n klik-hanteerder op die nuwe li te plaas:

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

Die kode van die hanteerder-funksie word eger nou gedupliceer in twee plekke - vir die oorspronklike li-elemente en vir die nuwe. Kom ons los dit op deur dit in 'n aparte funksie te plaas:

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

Laat ons ons funksie gebruik om duplisering van kode te vermy:

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);
});

Die probleem is oor die algemeen opgelos en ons het duplisering van die hanteerder-funksie se kode vermy. Eger moet ons steeds gebeurtenishanteerders op twee plekke plaas: beide in die lus vir bestaande li-elemente, en wanneer op die knoppie geklik word. In die volgende les sal ons 'n manier ondersoek om hierdie ongerief te verwyder.