17 of 17 menu

Fout met duplisering van DOM-elementredigeringsfunksie in JavaScript

Laat ons sê ons het 'n lys:

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

Laat ons die lys self en sy items in aparte veranderlikes kry:

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

Laat ons maak dat die items van ons lys met 'n verskynde invoerveld geredigeer kan word:

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

Laat ons nou sê ons wil nuwe items by die lys kan voeg. Laat daar vir hierdie doel 'n ooreenstemmende invoerveld onder die lys wees:

<input id="adder">

Laat ons 'n verwysing na hierdie invoerveld in 'n veranderlike kry:

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

Laat ons maak dat wanneer die invoerveld fokus verloor, 'n nuwe item met die teks wat uit ons invoerveld geneem is, by die lys gevoeg word:

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

Laat ons nou sê ons wil dat die nuutbygevoegde items ook geredigeer kan word. Op sigself sal redigering nie vir hulle werk nie, aangesien toe ons die klikhanterer op die lysitems geplaas het, hierdie items nog nie bestaan het nie.

Kom ons kyk na moontlike oplossings vir hierdie probleem.

Oplossing een

Die eenvoudigste oplossing is om die kode van funksie func te dupliseer deur dit ook vir nuutgeskepte items te koppel:

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

Natuurlik sien ons onmiddellik die nadeel in hierdie oplossing - dit is nie reg om kode te dupliseer nie.

Oplossing twee

Om die dupliseringsprobleem op te los, is dit logies om funksie func na buite te plaas en dit 'n Function Declaration te maak:

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

Hier wag die probleem op ons. Die ding is dat ons funksie die veranderlike li gebruik het, wat uit die buite-omvang verkry is. Maar nadat die funksie uitgeplaas is, is hierdie veranderlike nou nie meer sigbaar nie!

Om die probleem op te los, laat ons die li as 'n parameter oordra:

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

En hier skep ons oplossing nog 'n probleem. Die ding is dat jy nie net so 'n parameter in 'n gebeurtenishanterer kan oordra nie:

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

Om hierdie probleem op te los, roep ons eenvoudig ons funksie binne 'n anonieme hanterer:

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

En ons doen op 'n soortgelyke manier wanneer ons 'n nuwe lysitem skep:

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

Oplossing drie

Daar is 'n meer elegante oplossing. Ons kan eenvoudig gebeurtenisdelegasie gebruik. In hierdie geval sal die probleem met nuwe lysitems eenvoudig nie ontstaan nie:

ul.addEventListener('click', function(event) { if (event.target.tagName === 'LI') { // vang spesifiek klik op li, nie op invoer nie 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; }); } });

In hierdie geval sal die lus deur lysitems glad nie nodig wees nie, en die kode vir die skep van 'n nuwe lysitem sal verminder na so iets:

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; ul.append(li); });
Afrikaans
AzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarՀայերենIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Ons gebruik koekies vir die werking van die webwerf, ontleding en personalisering. Die verwerking van data geskied volgens die Privaatheidsbeleid.
aanvaar alles instel verwerp