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 = li.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 = li.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 = li.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 of 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हिन्दीMagyarՀայերենIndonesiaItaliano日本語Қазақ한국어КыргызчаLietuviųLatviešuМакедонскиMelayuမြန်မာNederlandsNorskPolskiPortuguêsRomânăРусскийසිංහලSlovenčinaSlovenščinaShqipСрпскиSrpskiSvenskaKiswahiliТоҷикӣไทยTürkmenTürkçeЎзбекOʻzbekTiếng Việt
ვებსაიტის მუშაობის, ანალიტიკისა და პერსონალიზაციისთვის ვიყენებთ ქუქი-ფაილებს. მონაცემთა დამუშავება ხდება Კონფიდენციალურობის პოლიტიკის შესაბამისად.
ყველას მიღება პარამეტრები უარყოფა