Uusien elementtien käsittelijöiden liittäminen JavaScriptissä
Oletetaan, että meillä on lista ul ja painike:
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<button>add</button>
Haetaan elementtimme vastaaviin muuttujiin:
let button = document.querySelector('button');
let list = document.querySelector('ul');
let items = list.querySelectorAll('li');
Tehdään niin, että minkä tahansa li:n napsautuksessa
siihen lisätään huutomerkki loppuun:
for (let item of items) {
item.addEventListener('click', function() {
this.textContent = this.textContent + '!';
});
}
Tehdään nyt niin, että painiketta painettaessa
listan loppuun lisätään uusi
li:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
list.appendChild(item);
});
Saamme kuitenkin ongelman: uuden lisätyn
li:n napsautus ei johda
huutomerkin lisäämiseen loppuun.
Asia on siinä, että lisäämme napsautuksen käsittelijän
vain niille li-elementeille, jotka olivat olemassa
alun perin, mutta ei uusille.
Korjataan ongelma liittämällä uuteen li:hin
napsautuksen käsittelijä:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', function() { // napsautuksen käsittelijä
this.textContent = this.textContent + '!';
});
list.appendChild(item);
});
Nyt kuitenkin käsittelijäfunktion koodi toistuu
kahdessa paikassa - alkuperäisille
li-elementeille ja uusille. Korjataan tämä erottamalla
se omaksi funktiokseen:
function handler() {
this.textContent = this.textContent + '!';
}
Käytetään funktiotamme välttääksemme koodin toistoa:
for (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);
});
Ongelma on periaatteessa ratkaistu ja vältyimme käsittelijäfunktion
koodin toistamiselta. Kuitenkin tapahtumakäsittelijöiden liittäminen
on edelleen tehtävä
kahdessa paikassa: sekä silmukassa olemassa oleville
li-elementeille että painikkeen napsautuksen yhteydessä. Seuraavassa
oppitunnissa käsittelemme tavan päästä eroon tästä
epämukavuudesta.