Makosa ya Kurudia Kazi ya Kurekebisha Vipengele vya DOM katika JavaScript
Wacha tuwe na orodha fulani:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Tutaipata orodha yenyewe na vitemi vyake katika anuwai tofauti:
let ul = document.querySelector('ul');
let lis = document.querySelectorAll('li');
Tufanye ili vitemi vya orodha yetu viweze kurekebishwa kwa kutumia kipengele cha uingizaji kinachoonekana:
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);
});
}
Wacha sasa tuhitaji kuwa na uwezo wa kuongeza vitemi vipya kwenye orodha. Wacha kwa hili chini ya orodha tuwe na kipengele cha uingizaji kinachofaa:
<input id="adder">
Tutaipata kiungo cha kipengele hiki cha uingizaji kwenye anuwai:
let adder = document.querySelector('#adder');
Tufanye ili, kupoteza umakini kwenye kipengele cha uingizaji, kiunge kwenye orodha kipya chenye maandishi, kuchukuliwa kutoka kwenye kipengele chetu cha uingizaji:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
ul.append(li);
});
Wacha sasa tuhitaji kuwa na uwezo wa kurekebisha hata vitemi vilivyoongezwa baadaye. Kwa ubinafsi, kurekebisha hakitaweza kufanya kazi kwao, kwani tulipoweka kisikizi cha kubonyeza kwenye vitemi vya orodha, vitemi hivi havikuwepo.
Wacha tuangalie chaguzi zinazowezekana za kutatua tatizo hili.
Suluhisho la Kwanza
Suluhisho rahisi zaidi - ni kurudia
msimbo wa kazi func, kuifungia
pia kwa vitemi vilivyoundwa baadaye:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
li.addEventListener('click', function func() {
// hapa tunarudia msimbo
});
ul.append(li);
});
Bila shaka, katika suluhisho hili tunaona mara moja upungufu - kurudia msimbo si sahihi.
Suluhisho la Pili
Ili kutatua tatizo la kurudia
kwa mantiki, toa kazi func
nje, ukiifanya kuwa Tamko la Kazi (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);
}
Hapa ndipo tatizo linatutegemea.
Jambo ni kwamba kazi yetu ilitumia
anuwai li, iliyopatikana
kutoka kwa eneo la nje la kuonekana.
Lakini baada ya kutoa kazi hii
anuwai sasa haionekani!
Ili kutatua tatizo tutapita
li yetu kama kigezo:
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);
}
Na hapa suluhisho letu linaleta tatizo jingine. Jambo ni kwamba haiwezekani kupitisha kigezo tu kwenye kisikizi cha tukio:
for (let li of lis) {
li.addEventListener('click', func(li)); // haifanyi kazi!
}
Ili kutatua tatizo hili ita kazi yetu ndani ya kisikizi cha kukokotoa kisichojulikana:
for (let li of lis) {
li.addEventListener('click', function() {
func(li);
});
}
Na kwa njia ile ile tutafanya wakati wa kuunda kipya cha orodha:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
li.addEventListener('click', function() {
func(li);
});
ul.append(li);
});
Suluhisho la Tatu
Kuna suluhisho la kifahari zaidi. Inawezekana kutumia mdelewa. Katika hili kesi tatizo na vitemi vipya la orodha haliwezi kutokea:
ul.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') { // tunakamata bonyezo kwenye li, sio kwenye kipengele cha uingizaji
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;
});
}
});
Katika kesi hii, mzunguko wa vitemi vya orodha kwa ujumla hautahitajika, na msimbo kwa kuunda kipya cha orodha utapunguzwa hadi hii:
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
ul.append(li);
});