17 of 17 menu

Chyba duplikovania funkcie pre editáciu DOM elementov v JavaScripte

Majme nejaký zoznam:

<ul> <li>1</li> <li>2</li> <li>3</li> </ul>

Získajme samotný zoznam a jeho položky do samostatných premenných:

let ul = document.querySelector('ul'); let lis = document.querySelectorAll('li');

Urobme tak, aby položky nášho zoznamu bolo možné editovať zobrazeným inputom:

for (let li of lis) { li.addEventListener('click', function func() { let input = document.createElement('input'); input.value = li.textContent; li.textContent = ''; li.append(input); input.addEventListener('blur', function() { li.textContent = this.value; li.addEventListener('click', func); }); li.removeEventListener('click', func); }); }

Povedzme teraz, že chceme, aby do zoznamu bolo možné pridávať nové položky. Nech preto pod zoznamom máme príslušný input:

<input id="adder">

Získajme odkaz na tento input do premennej:

let adder = document.querySelector('#adder');

Urobme tak, aby po strate focusu inputu do zoznamu pribudla nová položka s textom, prevzatým z nášho inputu:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; ul.append(li); });

Povedzme teraz, že chceme, aby aj novo pridané položky bolo tiež možné editovať. Samo od seba pre ne editovanie nebude fungovať, pretože keď sme zavesili obsluhu kliknutia na položky zoznamu, tieto položky ešte neexistovali.

Pozrime sa na možné varianty riešenia tohto problému.

Riešenie prvé

Najjednoduchšie riešenie - je zduplikovať kód funkcie func, pripojiac ju aj pre novo vytvorené položky:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; li.addEventListener('click', function func() { // tu duplikujeme kód }); ul.append(li); });

Samozrejme, v tomto riešení hneď vidíme nedostatok - duplikovať kód nie je správne.

Riešenie druhé

Na vyriešenie problému duplikovania je logické vyňať funkciu func von, čím z nej urobíme Function Declaration:

function func() { let input = document.createElement('input'); input.value = li.textContent; li.textContent = ''; li.append(input); input.addEventListener('blur', function() { li.textContent = this.value; li.addEventListener('click', func); }); li.removeEventListener('click', func); }

Tu nás ale čaká problém. Vec sa má tak, že naša funkcia používala premennú li, získanú z vonkajšej oblasti viditeľnosti. Ale po vyňatí funkcie táto premenná teraz nie je viditeľná!

Na vyriešenie problému budeme odovzdávať našu li parametrom:

function func(li) { let input = document.createElement('input'); input.value = li.textContent; li.textContent = ''; li.append(input); input.addEventListener('blur', function() { li.textContent = this.value; li.addEventListener('click', func); }); li.removeEventListener('click', func); }

A tu naše riešenie vytvára ešte jeden problém. Vec sa má tak, že nie je možné jednoducho odovzdať parameter do obsluhy udalosti:

for (let li of lis) { li.addEventListener('click', func(li)); // nefunguje! }

Na vyriešenie tohto problému jednoducho zavolajme našu funkciu vnútri anonymnej obsluhy:

for (let li of lis) { li.addEventListener('click', function() { func(li); }); }

A analogicky postupujme pri vytváraní novej položky zoznamu:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; li.addEventListener('click', function() { func(li); }); ul.append(li); });

Riešenie tretie

Existuje elegantnejšie riešenie. Môžeme jednoducho využiť delegovanie udalostí. V tomto prípade problém s novými položkami zoznamu jednoducho nevznikne:

ul.addEventListener('click', function(event) { if (event.target.tagName === 'LI') { // zachytávame konkrétne klik na li, nie na input let li = event.target; let input = document.createElement('input'); input.value = li.textContent; li.textContent = ''; li.append(input); input.addEventListener('blur', function() { li.textContent = this.value; }); } });

V tomto prípade cyklus cez položky zoznamu nám vôbec nebude potrebný a kód pre vytvorenie novej položky zoznamu sa zredukuje na takýto:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; ul.append(li); });
Slovenčina
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Používame cookies na fungovanie stránky, analýzu a personalizáciu. Spracúvanie údajov prebieha v súlade s Politikou ochrany osobných údajov.
prijať všetky nastaviť odmietnuť