17 of 17 menu

DOM տարրերի խմբագրման ֆունկցիայի կրկնօրինակման սխալը JavaScript-ում

Ենթադրենք՝ ունենք ինչ-որ ցուցակ.

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

Ստացենք հենց ցուցակը և դրա կետերը առանձին փոփոխականների մեջ.

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

Եկեք այնպես անենք, որ մեր ցուցակի կետերը հնարավոր լինի խմբագրել հայտնվող ինպուտի միջոցով.

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

Ենթադրենք հիմա ուզում ենք, որ ցուցակին հնարավոր լինի ավելացնել նոր կետեր. Ենթադրենք դրա համար ցուցակի տակ մենք ունենք համապատասխան ինպուտ.

<input id="adder">

Ստացենք այս ինպուտի հղումը փոփոխականի մեջ.

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

Եկեք այնպես անենք, որ ինպուտի ֆոկուսի կորստի դեպքում ցուցակին ավելանա նոր կետ մեր ինպուտից վերցված տեքստով.

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

Ենթադրենք հիմա ուզում ենք, որ նոր ավելացված կետերը նույնպես հնարավոր լինի խմբագրել: Ինքնին դրանց համար խմբագրումը չի աշխատի, քանի որ երբ մենք կախում էինք կլիկի հենդլերը ցուցակի կետերի վրա, այդ կետերն այդ ժամանակ դեռ չկային:

Եկեք նայենք այս խնդիրը լուծելու հնարավոր տարբերակներին:

Առաջին լուծումը

Ամենապարզ լուծումը՝ կրկնօրինակել func ֆունկցիայի կոդը, կապելով այն նաև նոր ստեղծված կետերի համար.

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; li.addEventListener('click', function func() { // այստեղ մենք կրկնօրինակում ենք կոդը }); ul.append(li); });

Իհարկե, այս լուծման մեջ մենք անմիջապես տեսնում ենք թերությունը՝ կոդը կրկնօրինակելը ճիշտ չէ:

Երկրորդ լուծումը

Կրկնօրինակման խնդիրը լուծելու համար տրամաբանական է func ֆունկցիան դուրս բերել՝ այն դարձնելով Function Declaration.

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

Ահա այստեղ է մեզ սպասում խնդիրը: Բանն այն է, որ մեր ֆունկցիան օգտագործում էր li փոփոխականը, որը ստացվել էր արտաքին տեսանելիության տիրույթից: Բայց ֆունկցիան դուրս բերելուց հետո այդ փոփոխականն այժմ տեսանելի չէ:

Խնդիրը լուծելու համար մենք կփոխանցենք մեր li-ը պարամետրով.

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

Եվ ահա մեր լուծումը ծնում է ևս մեկ խնդիր: Բանն այն է, որ պարզապես հնարավոր չէ պարամետր փոխանցել իվենթի հենդլերին.

for (let li in lis) { li.addEventListener('click', func(li)); // չի աշխատում! }

Այս խնդիրը լուծելու համար պարզապես կանվանենք մեր ֆունկցիան անանուն հենդլերի ներսում.

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

Եվ նմանապես վարվենք ցուցակի նոր կետ ստեղծելիս.

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

Երրորդ լուծումը

Գոյություն ունի ավելի նրբագեղ լուծում: Կարելի է պարզապես օգտագործել դելեգացումը: Այս դեպքում ցուցակի նոր կետերի հետ կապված խնդիրը պարզապես չի առաջանա.

ul.addEventListener('click', function(event) { if (event.target.tagName === 'LI') { // բռնում ենք հենց li-ի վրա կլիկը, ոչ թե ինպուտի վրա 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; }); } });

Այս դեպքում ցուցակի կետերով ցիկլը ընդհանրապես մեզ պետք չի լինի, իսկ կոդը նոր ցուցակի կետ ստեղծելու համար կկրճատվի մինչև այսպիսին.

adder.addEventListener('blur', function() { let li = document.createElement('li'); li.textContent = this.value; ul.append(li); });
Հայերեն
AfrikaansAzərbaycanБългарскиবাংলাБеларускаяČeštinaDanskDeutschΕλληνικάEnglishEspañolEestiSuomiFrançaisहिन्दीMagyarIndonesiaItaliano日本語ქართულიҚазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
Մենք օգտագործում ենք cookie-ներ կայքի աշխատանքի, վերլուծության և անհատականացման համար։ Տվյալների մշակումը կատարվում է համաձայն Գաղտնիության քաղաքականության։
ընդունել բոլորը կարգավորել մերժել