รูปแบบการมอบหมายเหตุการณ์
จัดการเหตุการณ์ของลูกหลายตัวจากตัวรับฟังเดียวที่พาเรนต์
รูปแบบการมอบหมายเหตุการณ์ เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
ตัวรับฟังเดียวควบคุมทั้งหมด
การมอบหมายเหตุการณ์ หมายถึงการผูกตัวรับฟังเพียงตัวเดียวไว้กับองค์ประกอบบรรพบุรุษร่วม แทนการผูกตัวรับฟังหลายตัวไว้กับองค์ประกอบลูกแต่ละตัว เนื่องจากเหตุการณ์ไหลย้อนขึ้น องค์ประกอบแม่จึงได้รับการคลิกจากองค์ประกอบลูกหลานทั้งหมด
<ul id="menu">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>แนวทางแบบตรงไปตรงมา
หากไม่ใช้การมอบหมายเหตุการณ์ คุณจะวนซ้ำผ่านรายการทุกชิ้นแล้วผูกตัวจัดการไว้กับแต่ละชิ้น วิธีนี้สิ้นเปลือง เพราะใช้หน่วยความจำมากขึ้นและไม่ทำงานกับองค์ประกอบที่เพิ่มเข้ามาภายหลัง
document.querySelectorAll("#menu li").forEach((li) => {
li.addEventListener("click", () => console.log(li.textContent));
});แนวทางแบบมอบหมายเหตุการณ์
ให้ผูกตัวรับฟังเพียงตัวเดียวไว้กับองค์ประกอบแม่แทน แล้วตรวจสอบ event.target เพื่อค้นหาว่าองค์ประกอบลูกใดถูกคลิก
const menu = document.getElementById("menu");
menu.addEventListener("click", (e) => {
console.log(e.target.textContent);
});การจับคู่เป้าหมายที่ถูกต้อง
การคลิกอาจตกลงบนองค์ประกอบที่ซ้อนอยู่ภายใน ให้ใช้ event.target.closest(selector) เพื่อไล่ขึ้นไปและค้นหาองค์ประกอบบรรพบุรุษที่เกี่ยวข้องซึ่งตรงกับตัวเลือกของคุณ
menu.addEventListener("click", (e) => {
const item = e.target.closest("li");
if (!item) return; // clicked outside any li
console.log("Clicked:", item.textContent);
});การป้องกันด้วยการตรวจสอบ
ควรป้องกันกรณีการคลิกที่ไม่ตรงกับเงื่อนไขเสมอ การออกจากการทำงานตั้งแต่ต้นด้วย if (!item) return; ช่วยไม่ให้ตัวจัดการทำงานผิดพลาดเมื่อผู้ใช้คลิกพื้นที่ว่างหรือช่องว่างภายในองค์ประกอบบรรจุ
menu.addEventListener("click", (e) => {
const item = e.target.closest("li");
if (!item || !menu.contains(item)) return;
handleSelect(item);
});การใช้แอตทริบิวต์ข้อมูล
รูปแบบที่ใช้กันทั่วไปคือจัดเก็บรหัสหรือการทำงานไว้กับแต่ละรายการด้วยแอตทริบิวต์ data-* จากนั้นตัวจัดการที่ได้รับมอบหมายจะอ่านค่าจากองค์ประกอบที่จับคู่ได้
menu.addEventListener("click", (e) => {
const item = e.target.closest("li");
if (!item) return;
const id = item.dataset.id; // reads data-id
console.log("Selected id:", id);
});การแยกการทำงานตามการกระทำ
สำหรับแถบเครื่องมือที่มีปุ่มจำนวนมาก ให้กำหนด data-action ให้แต่ละปุ่ม แล้วใช้ค่านั้นแยกการทำงาน ตัวรับฟังเพียงตัวเดียวจะจัดการปุ่มทั้งหมด
toolbar.addEventListener("click", (e) => {
const btn = e.target.closest("button");
if (!btn) return;
switch (btn.dataset.action) {
case "save": save(); break;
case "delete": remove(); break;
}
});เหตุใดจึงรองรับการขยายขนาด
เมื่อใช้การมอบหมายเหตุการณ์ รายการที่มี 1,000 แถวต้องใช้ตัวรับฟังเพียงตัวเดียวแทนที่จะใช้ 1,000 ตัว วิธีนี้ใช้หน่วยความจำน้อยกว่า เริ่มต้นได้เร็วกว่า และไม่ต้องมีวงวนล้างข้อมูลเมื่อแถวต่าง ๆ เปลี่ยนแปลง
หมายเหตุด้านประสิทธิภาพ
การมอบหมายเหตุการณ์มีต้นทุนเล็กน้อยเช่นกัน เหตุการณ์ที่ตรงกับเงื่อนไขทุกเหตุการณ์จะเรียกใช้ตัวจัดการของคุณ แล้วตัวจัดการจึงคัดกรองต่อ สำหรับแอปส่วนใหญ่ ต้นทุนนี้น้อยมากเมื่อเทียบกับประโยชน์ที่ได้ แต่ควรหลีกเลี่ยงการผูกตัวรับฟังแบบมอบหมายไว้กับ document สำหรับเหตุการณ์ความถี่สูงมาก เช่น mousemove
การเลือกองค์ประกอบบรรจุ
เลือกองค์ประกอบบรรพบุรุษที่คงอยู่ใกล้ที่สุดและบรรจุเป้าหมายทั้งหมด การมอบหมายให้กับองค์ประกอบบรรจุที่เฉพาะเจาะจง เช่น ตัวรายการเอง ดีกว่าการมอบหมายให้กับ document เพราะจะมีเหตุการณ์ที่ไม่เกี่ยวข้องเรียกใช้ตัวจัดการของคุณน้อยกว่า
const list = document.querySelector(".task-list");
list.addEventListener("click", onTaskClick);การใช้ร่วมกับ closest
closest() คือหัวใจของการมอบหมายเหตุการณ์ โดยจะคืนค่าองค์ประกอบนั้นเองหากตรงกับเงื่อนไข หรือคืนค่าองค์ประกอบบรรพบุรุษที่ตรงเงื่อนไขและอยู่ใกล้ที่สุด หรือคืนค่า null วิธีนี้ทำให้สามารถใช้การมอบหมายกับโครงสร้างมาร์กอัปที่ซ้อนกันได้อย่างปลอดภัย
const cell = e.target.closest("td[data-col]");
if (cell) console.log(cell.dataset.col);ตรวจสอบความเข้าใจ
เหตุใดจึงควรใช้การมอบหมายเหตุการณ์
ทบทวน
การมอบหมายเหตุการณ์จะผูกตัวรับฟังหนึ่งตัวไว้กับองค์ประกอบแม่ และใช้การไหลย้อนขึ้นเพื่อจัดการองค์ประกอบลูกทั้งหมด ใช้ e.target.closest(selector) เพื่อค้นหาองค์ประกอบที่เกี่ยวข้อง ป้องกันด้วยการคืนค่าตั้งแต่ต้น และอ่านแอตทริบิวต์ data-* เพื่อแยกการทำงาน วิธีนี้รองรับรายการขนาดใหญ่มากและเป็นรูปแบบมาตรฐานสำหรับส่วนติดต่อผู้ใช้แบบไดนามิก
คำถามที่พบบ่อย
บทเรียน “รูปแบบการมอบหมายเหตุการณ์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบการมอบหมายเหตุการณ์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบการมอบหมายเหตุการณ์”
จัดการเหตุการณ์ของลูกหลายตัวจากตัวรับฟังเดียวที่พาเรนต์ คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบการมอบหมายเหตุการณ์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม
ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ระยะจับเหตุการณ์และระยะ bubbling
- รูปแบบการมอบหมายเหตุการณ์
- รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์
- เหตุการณ์กำหนดเอง