การติดตั้งตัวจัดการเหตุการณ์บนองค์ประกอบใหม่ใน JavaScript
สมมติว่าเรามีรายการ ul และปุ่ม:
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
<button>add</button>
รับองค์ประกอบของเราเข้าไปในตัวแปรที่เกี่ยวข้อง:
let button = document.querySelector('button');
let list = document.querySelector('ul');
let items = list.querySelectorAll('li');
มาทำให้เมื่อคลิกที่ li ใด ๆ
เครื่องหมายอัศเจรีย์จะถูกเพิ่มไปที่ท้ายของมัน:
for (let item of items) {
item.addEventListener('click', function() {
this.textContent = this.textContent + '!';
});
}
ตอนนี้มาทำให้เมื่อกดปุ่ม
li ใหม่จะถูกเพิ่มไปที่ท้ายรายการ:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
list.appendChild(item);
});
อย่างไรก็ตาม เราจะได้ปัญหามา: การคลิกที่
li ที่เพิ่มเข้ามาใหม่จะไม่ส่งผลให้
เพิ่มเครื่องหมายอัศเจรีย์ที่ท้าย
เหตุผลก็คือ เราเพิ่มตัวจัดการการคลิก
เฉพาะกับ li ที่มีอยู่ตั้งแต่แรก
แต่ ไม่ได้เพิ่มให้กับอันใหม่
มาแก้ไขปัญหาด้วยการติดตั้งตัวจัดการการคลิกบน li ใหม่:
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', function() { // ตัวจัดการการคลิก
this.textContent = this.textContent + '!';
});
list.appendChild(item);
});
อย่างไรก็ตาม ตอนนี้โค้ดของฟังก์ชันตัวจัดการซ้ำซ้อน
ในสองที่ - สำหรับ li ที่มีอยู่ตั้งแต่แรก
และสำหรับอันใหม่ มาแก้ไขโดยแยกมันออกมาเป็นฟังก์ชันแยก:
function handler() {
this.textContent = this.textContent + '!';
}
ใช้ฟังก์ชันของเราเพื่อหลีกเลี่ยงการซ้ำซ้อนของโค้ด:
for (let item of items) {
item.addEventListener('click', handler);
}
button.addEventListener('click', function() {
let item = document.createElement('li');
item.textContent = 'item';
item.addEventListener('click', handler);
list.appendChild(item);
});
โดยทั่วไปปัญหาได้รับการแก้ไขแล้ว และเราหลีกเลี่ยงการซ้ำซ้อน
ของโค้ดฟังก์ชันตัวจัดการ อย่างไรก็ตาม การติดตั้ง
ตัวจัดการเหตุการณ์ยังคงต้องทำในสองที่: ทั้งในลูปสำหรับ li ที่มีอยู่
และเมื่อคลิกที่ปุ่ม ในบทเรียนหน้าเราจะพูดถึงวิธีกำจัดความไม่สะดวกนี้