0Pricing
JavaScript Academy · บทเรียน

รูปแบบการมอบหมายเหตุการณ์

จัดการเหตุการณ์ของลูกหลายตัวจากตัวรับฟังเดียวที่พาเรนต์

รูปแบบการมอบหมายเหตุการณ์ เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ระยะจับเหตุการณ์และระยะ bubbling
  2. รูปแบบการมอบหมายเหตุการณ์
  3. รายการแบบไดนามิกด้วยการมอบหมายเหตุการณ์
  4. เหตุการณ์กำหนดเอง
← กลับไปที่ JavaScript Academy