17 of 17 menu

Greška dupliciranja funkcije za uređivanje DOM elemenata u JavaScriptu

Pretpostavimo da imamo neki spisak:

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

Uzmimo sam spisak i njegove stavke u posebne promenljive:

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

Učinimo da se stavke našeg spiska mogu uređivati pomoću pojavljujućeg input polja:

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

Pretpostavimo sada da želimo da u spisak moguće je dodavati nove stavke. Neka ispod spiska postoji odgovarajuće input polje za to:

<input id="adder">

Uzmimo referencu na ovo input polje u promenljivu:

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

Učinimo da se gubitkom fokusa input polja u spisak doda nova stavka sa tekstom, preuzetim iz našeg input polja:

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

Pretpostavimo sada da želimo da se i novododate stavke takođe mogu uređivati. Samo po sebi za njih uređivanje neće raditi, jer kada smo postavljali osluškivač klika na stavke spiska, tih stavki još nije bilo.

Pogledajmo moguće varijante rešavanja ovog problema.

Prvo rešenje

Najjednostavnije rešenje je dupliciranje koda funkcije func, povezujući je i za novokreirane stavke:

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

Naravno, u ovom rešenju odmah vidimo nedostatak - duplicirati kod nije ispravno.

Drugo rešenje

Za rešavanje problema dupliciranja logično je izneti funkciju func napolje, napravivši je kao 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); }

Ovde nas upravo čeka problem. Stvar je u tome što je naša funkcija koristila promenljivu li, dobijenu iz spoljašnje oblasti vidljivosti. Ali nakon iznošenja funkcije ova promenljiva sada nije vidljiva!

Za rešavanje problema prosledićemo našu li kao parametar:

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

I ovde naše rešenje stvara još jedan problem. Stvar je u tome što ne možemo tek tako proslediti parametar u osluškivač događaja:

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

Za rešavanje ovog problema jednostavno ćemo pozvati našu funkciju unutar anonimnog osluškivača:

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

I na isti način ćemo postupiti prilikom kreiranja nove stavke spiska:

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

Treće rešenje

Postoji i elegantnije rešenje. Možemo jednostavno iskoristiti delegiranje. U ovom slučaju problem sa novim stavkama spiska jednostavno neće nastati:

ul.addEventListener('click', function(event) { if (event.target.tagName === 'LI') { // hvata upravo klik na li, ne 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; }); } });

U ovom slučaju petlja po stavkama spiska nam uopšte neće trebati, a kod za kreiranje nove stavke spiska smanjiće se na ovo:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; ul.append(li); });
Srpski
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Koristimo kolačiće za rad sajta, analitiku i personalizaciju. Obrada podataka se vrši u skladu sa Politikom privatnosti.
prihvati sve podesi odbij