JavaScript-de DOM elementlerini redaktirlemek funksiýasynyň dublikasi ýalňyşlygy
Bizde käbir sanaw bar diýeliň:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Sanawy we onuň maddalaryny aýratyn üýtgeýjilere alýarys:
let ul = document.querySelector('ul');
let lis = document.querySelectorAll('li');
Sanawymyzyň maddalaryny peýda bolýan input arkaly redaktirläp boljak etmeli:
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);
});
}
Indi sanawa täze maddalar goşup boljak etmek isleýäris diýeliň. Bunun üçin sanawyň aşagynda degişli input bolsun:
<input id="adder">
Bu inputa salgyny üýtgeýjide alýarys:
let adder = document.querySelector('#adder');
Inputdan fokus aýrylanda, inputdan alnan tekst bilen sanawa täze madda goşulýandygy ýaly edeliň:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
ul.append(li);
});
Indi täze goşulan maddalary hem redaktirläp boljak etmek isleýäris. Öz-özüne, olar üçin redaktirleme işlemez, sebäbi biz sanaw maddalaryna çykyş işleşdirijini goýlanda, bu maddalar ýokdy.
Bu meseleni çözmegiň mümkin bolan wariantlaryna seredeliň.
Birinci çözgüt
Iň ýönekeý çözgüt – bu func funksiýasynyň kodyny täze döredilen maddalar üçin hem baglamak arkaly ikilenmekdir:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
li.addEventListener('click', function func() {
// şu ýerde kody ikiledýäris
});
ul.append(li);
});
Elbette, bu çözgütde derrew kemçiligi görýäris – kody ikilemek dogry däl.
Ikinji çözgüt
Ikilemek problemasyny çözmek üçin func funksiýasyny çykarmak we ony Function Declaration etmek mälimdir:
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);
}
Şu ýerde problem bizi gözleýär.
Sebäbi, biziň funksiýamyz daşyndaky görüş meýdanyndan alnan li üýtgeýjisini ulandy.
Emma funksiýany çykardan soň, bu üýtgeýji indi görünmeýär!
Problemi çözmek üçin biziň li üýtgeýjimizi parametr hökmünde geçireris:
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);
}
We şu ýerde biziň çözgüdimiz ýene bir problem döredýär. Sebäbi, waka işleşdirijisine parametri ýönekeý ýagdaýda geçip bolmaýar:
for (let li of lis) {
li.addEventListener('click', func(li)); // işlemeýär!
}
Bu meseläni çözmek üçin, biziň funksiýamyzy anonim işleşdiriji içinde çagyralyň:
for (let li of lis) {
li.addEventListener('click', function() {
func(li);
});
}
We şuňa meňzeş ýagdaýda täze sanaw maddasyny döredende hem edeliň:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
li.addEventListener('click', function() {
func(li);
});
ul.append(li);
});
Üçünji çözgüt
Has owadan çözgüt bar. Biz ýönekeý ýagdaýda delegasiýany ulanyp bilýäris. Bu ýagdaýda täze sanaw maddalary bilen baglanyşykly mesele ýüze çykmaz:
ul.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') { // li-a basylyşy, input-däl, tutýarys
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;
});
}
});
Bu ýagdaýda sanaw maddalary boýunça aýlaw biz üçin umuman zerur bolmaz, we täze sanaw maddasyny döretmek üçin kod şuňa çenli gysgalar:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
ul.append(li);
});