รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์
จัดการเหตุการณ์ขององค์ประกอบที่เพิ่มขณะรันไทม์
รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์ เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ปัญหาองค์ประกอบแบบไดนามิก
เมื่อคุณผูกตัวรับฟังไว้กับองค์ประกอบโดยตรง องค์ประกอบใดก็ตามที่ถูกเพิ่มลงใน DOM หลังจากการตั้งค่าจะไม่มีตัวรับฟัง การมอบหมายเหตุการณ์แก้ปัญหานี้ได้ เพราะตัวรับฟังขององค์ประกอบแม่จะจับเหตุการณ์จากองค์ประกอบลูกที่เพิ่มขึ้นในภายหลังได้ด้วย
ตัวรับฟังโดยตรงทำงานผิดพลาด
ในที่นี้ ตัวรับฟังถูกเพิ่มให้กับรายการที่มีอยู่แล้ว รายการที่เพิ่มเข้ามาใหม่จะไม่ได้รับอะไรเลยและยังคงไม่ทำงาน
document.querySelectorAll(".item").forEach((el) =>
el.addEventListener("click", handle)
);
list.appendChild(newItem); // newItem has NO handlerการมอบหมายทำงานได้ทันที
เมื่อมีตัวรับฟังแบบมอบหมายอยู่บนองค์ประกอบแม่ รายการใหม่จะได้รับการจัดการโดยอัตโนมัติ ไม่จำเป็นต้องผูกตัวรับฟังใหม่หลังการแทรกแต่ละครั้ง
list.addEventListener("click", (e) => {
const item = e.target.closest(".item");
if (item) console.log("Clicked", item.dataset.id);
});
list.appendChild(newItem); // works immediatelyการเพิ่มรายการ
สร้างองค์ประกอบใหม่แล้วเพิ่มองค์ประกอบเหล่านั้นเข้าไป เนื่องจากองค์ประกอบแม่มีการมอบหมายอยู่แล้ว องค์ประกอบเหล่านั้นจึงโต้ตอบได้ทันทีที่ปรากฏขึ้น
function addItem(text) {
const li = document.createElement("li");
li.className = "item";
li.textContent = text;
list.appendChild(li);
}การลบรายการ
การลบก็ทำได้อย่างสะอาดเช่นกัน ตัวจัดการแบบมอบหมายสามารถตรวจพบปุ่มลบภายในแถวแล้วลบแถวนั้นได้
list.addEventListener("click", (e) => {
if (e.target.matches(".delete-btn")) {
e.target.closest(".item").remove();
}
});การแยกการกระทำย่อย
แถวหนึ่งอาจมีส่วนที่โต้ตอบได้หลายส่วน ใช้ matches() หรือ closest() เพื่อระบุว่าส่วนใดถูกคลิก แล้วจึงแยกการทำงานตามนั้น
list.addEventListener("click", (e) => {
if (e.target.matches(".edit-btn")) edit(e);
else if (e.target.matches(".delete-btn")) del(e);
});การแสดงผลจากข้อมูล
รูปแบบที่ใช้กันทั่วไปคือเก็บสถานะไว้ในอาร์เรย์ แสดงผลแถวจากสถานะนั้น และมอบหมายการคลิก การแสดงผลใหม่จะแทนที่องค์ประกอบลูก แต่ตัวรับฟังเพียงตัวเดียวบนองค์ประกอบแม่จะยังคงอยู่โดยไม่เปลี่ยนแปลง
function render(items) {
list.innerHTML = items
.map((i) => "<li class=\"item\" data-id=\"" + i.id + "\">" + i.name + "</li>")
.join("");
}ไม่ต้องยุ่งยากกับการล้างข้อมูล
เมื่อใช้ตัวรับฟังแยกกันในแต่ละองค์ประกอบ คุณต้องจำให้ได้ว่าต้องเรียก removeEventListener ก่อนลบโหนด เพื่อป้องกันหน่วยความจำรั่ว การมอบหมายเหตุการณ์ช่วยขจัดภาระนี้ เพราะการลบองค์ประกอบลูกจะไม่ทำให้ตัวรับฟังใด ๆ ค้างอยู่โดยไม่มีเจ้าของ
การสลับคลาส
การมอบหมายเหตุการณ์ทำงานร่วมกับการสลับคลาสเพื่อแสดงสถานะการเลือกได้เป็นอย่างดี ตัวจัดการจะค้นหาแถวแล้วสลับคลาสให้
list.addEventListener("click", (e) => {
const row = e.target.closest(".item");
if (row) row.classList.toggle("selected");
});การอ่านข้อมูลระบุตัวตนที่คงที่
เนื่องจากโหนด DOM จะถูกแทนที่เมื่อแสดงผลใหม่ จึงไม่ควรเก็บการอ้างอิงไปยังโหนดเหล่านั้น ให้เก็บรหัสที่คงที่ไว้ใน data-id แล้วค้นหาข้อมูลในแบบจำลองข้อมูลด้วยรหัสดังกล่าวภายในตัวจัดการ
const id = e.target.closest(".item").dataset.id;
const record = state.find((r) => r.id === id);เหตุการณ์การป้อนข้อมูลก็ใช้ได้เช่นกัน
การมอบหมายเหตุการณ์ไม่ได้จำกัดอยู่แค่การคลิก คุณสามารถมอบหมายเหตุการณ์ input หรือ change สำหรับช่องแบบฟอร์มที่เพิ่มเข้ามาแบบไดนามิกได้ในลักษณะเดียวกัน
form.addEventListener("input", (e) => {
if (e.target.matches(".qty")) recalc(e.target);
});ตรวจสอบความเข้าใจ
รายการแบบไดนามิกและการมอบหมายเหตุการณ์
ทบทวน
การมอบหมายเหตุการณ์เหมาะอย่างยิ่งกับรายการแบบไดนามิก ตัวรับฟังหนึ่งตัวบนองค์ประกอบแม่จะจัดการทั้งองค์ประกอบลูกที่มีอยู่และองค์ประกอบลูกในอนาคต อยู่รอดได้เมื่อแสดงผลใหม่ และไม่ต้องล้างข้อมูลแยกตามโหนด ใช้ matches() และ closest() เพื่อแยกการกระทำย่อย และเก็บรหัสที่คงที่ไว้ใน data-* เพื่อให้ตัวจัดการค้นหาแบบจำลองข้อมูลได้
คำถามที่พบบ่อย
บทเรียน “รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์”
จัดการเหตุการณ์ขององค์ประกอบที่เพิ่มขณะรันไทม์ คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม
ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ระยะจับเหตุการณ์และระยะ bubbling
- รูปแบบการมอบหมายเหตุการณ์
- รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์
- เหตุการณ์กำหนดเอง