17 of 17 menu

A DOM elemek szerkesztésére szolgáló függvény ismétlődő hibája JavaScriptben

Tegyük fel, hogy van egy listánk:

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

Kérjük le magát a listát és annak elemeit külön változókba:

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

Tegyük lehetővé, hogy a listánk elemeit egy megjelenő input mezővel lehessen szerkeszteni:

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

Tegyük fel most, hogy azt szeretnénk, hogy a listába lehessen új elemeket hozzáadni. Tegyük fel, hogy ehhez a lista alatt lesz egy megfelelő input mező:

<input id="adder">

Kérjük le ezt az input mezőt egy változóba:

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

Tegyük lehetővé, hogy amikor az input mező elveszti a fókuszt, akkor a listához adjon hozzá egy új elemet a szöveggel, amely az input mezőből származik:

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

Tegyük fel most, hogy azt szeretnénk, hogy az újonnan hozzáadott elemeket is lehessen szerkeszteni. Önmagában a szerkesztés nem fog működni rájuk, mert amikor a kattintás eseménykezelőt rendeltük a listaelemekhez, ezek az elemek még nem is léteztek.

Nézzük meg a lehetséges megoldási lehetőségeket erre a problémára.

Első megoldás

A legegyszerűbb megoldás - hogy megkettézzük a func függvény kódját, összekötve azt az újonnan létrehozott elemekkel is:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; li.addEventListener('click', function func() { // itt megkettézzük a kódot }); ul.append(li); });

Természetesen ebben a megoldásban azonnal látjuk a hátrányt - a kód megkettőzése nem helyes.

Második megoldás

A megkettőzés problémájának megoldása érdekében logikus a func függvényt kívülre helyezni, Function Declaration-né téve:

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

Itt vár ránk a probléma. Az a helyzet, hogy a függvényünk használta a li változót, amelyet a külső hatókörből kaptunk. De a függvény kívülre helyezése után ez a változó már nem látható!

A probléma megoldása érdekében adjuk át a li változót paraméterként:

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

És itt a megoldásunk egy további problémát vet fel. Az a helyzet, hogy nem lehet egyszerűen paramétert átadni egy eseménykezelőnek:

for (let li of lis) { li.addEventListener('click', func(li)); // nem működik! }

A probléma megoldásához egyszerűen hívjuk meg a függvényünket egy névtelen eseménykezelőn belül:

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

És hasonlóan járjunk el az új listaelem létrehozásakor:

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

Harmadik megoldás

Létezik egy elegánsabb megoldás is. Egyszerűen használhatjuk a delegálást. Ebben az esetben az új listaelemekkel kapcsolatos probléma egyszerűen nem fog felmerülni:

ul.addEventListener('click', function(event) { if (event.target.tagName === 'LI') { // pontosan az li-re kattintást fogjuk el, nem az inputra 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; }); } });

Ebben az esetben a listaelemeken való ciklus egyáltalán nem is lesz szükséges, és az új listaelem létrehozásához szükséges kód ilyenre rövidül:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; ul.append(li); });
Magyar
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
A weboldal működéséhez, elemzéshez és személyre szabáshoz sütiket használunk. Az adatfeldolgozás a Adatvédelmi irányelvek szerint történik.
összes elfogadása beállítás elutasítás