JavaScript တွင် DOM အစိတ်အပိုင်းများကို တည်းဖြတ်သည့် လုပ်ဆောင်ချက် ထပ်တူပြုမှု အမှား
ကျွန်ုပ်တို့တွင် စာရင်းတစ်ခုရှိသည်ဆိုပါစို့။
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
စာရင်းကိုယ်နှိုက်နှင့် ၎င်း၏အမှတ်များကို သီးခြားကိန်းရှင်များအဖြစ် ရယူကြပါစို့။
let ul = document.querySelector('ul');
let lis = document.querySelectorAll('li');
ကျွန်ုပ်တို့၏ စာရင်းအမှတ်များကို �ေါ်လာသော input များဖြင့် တည်းဖြတ်နိုင်စေရန် လုပ်ဆောင်ပါမည်။
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 တစ်ခုရှိပါစို့။
<input id="adder">
ဤ input အတွက် reference ကို ကိန်းရှင်ထဲသို့ ရယူပါမည်။
let adder = document.querySelector('#adder');
input ၏ focus ပျောက်သွားသောအခါ ကျွန်ုပ်တို့၏ input မှ ယူထားသော စာသားဖြင့် စာရင်းထဲသို့ အသစ်သောအမှတ်တစ်ခု ထည့်သွင်းပေးစေရန် လုပ်ဆောင်ပါမည်။
adder.addEventListener('blur', function() {
let li = document.createElement('li');
li.textContent = this.value;
ul.append(li);
});
ယခု ကျွန်ုပ်တို့သည် ထပ်မံထည့်သွင်းထားသော အမှတ်များကိုလည်း �ည်းဖြတ်နိုင်စေလိုပါသည်။ စာရင်းအမှတ်များအပေါ် click event listener များ ချိတ်ဆက်ခဲ့သည့်အခါ ထိုအမှတ်များ မရှိသေးသောကြောင့် ၎င်းတို့အတွက် တည်းဖြတ်မှုက သူ့အလိုလို အလုပ်လုပ်မည် မဟုတ်ပါ။
ဤပြဿနာကို ဖြေရှင်းနိုင်သည့် နည်းလမ်းများကို ကြည့်ရှုကြည့်ပါမည်။
ပထမဆုံး ဖြေရှင်းချက်
အရှင်းဆုံးသော ဖြေရှင်းချက်မှာ
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);
}
ဤနေရာမှာပင် ပြဿနာက ကျွန်ုပ်တို့ကို စောင့်မျှော်နေပါသည်။
အကြောင်းမှာ ကျွန်ုပ်တို့၏ လုပ်ဆောင်ချက်သည်
အပြင်ဘက် scope မှ ရယူထားသော li
ကိန်းရှင်ကို အသုံးပြုထားသောကြောင့် ဖြစ်သည်။
သို့သော် လုပ်ဆောင်ချက်ကို ထုတ်ယူပြီးနောက်
ယခုအခါ ထိုကိန်းရှင်ကို မြင်နိုင်စွမ်း မရှိတော့ပါ။
ပြဿနာကို ဖြေရှင်းရန် ကျွန်ုပ်တို့၏
li ကို parameter အဖြစ် ပို့ဆောင်ပေးပါမည်။
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);
}
ဤနေရာတွင် ကျွန်ုပ်တို့၏ ဖြေရှင်းချက်သည် နောက်ထပ် ပြဿနာတစ်ခုကို ဖန်တီးပေးပါသည်။ အကြောင်းမှာ event listener တစ်ခုအတွင်းသို့ parameter တစ်ခုကို ရိုးရိုးရှင်းရှင်း ပို့ဆောင်လို့မရပါ။
for (let li of lis) {
li.addEventListener('click', func(li)); // အလုပ်မလုပ်ပါ။
}
ဤပြဿနာကို ဖြေရှင်းရန် ကျွန်ုပ်တို့၏ လုပ်ဆောင်ချက်ကို anonymous event listener တစ်ခုအတွင်းမှ ခေါ်ယူပါမည်။
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);
});
တတိယ ဖြေရှင်းချက်
ပို၍ ကျက်သရေရှိသော ဖြေရှင်းချက် တစ်ခု ရှိပါသည်။ အပ်နှံခြင်း (Delegation) ကို ရိုးရှင်းစွာ အသုံးပြုနိုင်ပါသည်။ ဤကိစ္စတွင် အသစ်သော စာရင်းအမှတ်များနှင့်ပတ်သက်သည့် ပြဿနာသည် ပေါ်လာမည် မဟုတ်တော့ပါ။
ul.addEventListener('click', function(event) {
if (event.target.tagName === 'LI') { // li ပေါ်တွင် နှိပ်သည်ကိုသာ ဖမ်းယူသည်၊ input ပေါ်တွင် နှိပ်သည်ကို မဟုတ်ပါ။
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);
});