ความแตกต่างระหว่าง event.preventDefault() และ event.stopPropagation() ใน JavaScript

ความแตกต่างระหว่าง event.preventDefault() และ event.stopPropagation() ใน JavaScript

เมื่อเขียน JavaScript สำหรับจัดการเหตุการณ์ (event), นักพัฒนาหลายคนอาจสับสนระหว่าง event.preventDefault() และ event.stopPropagation() เนื่องจากทั้งสองคำสั่งมีหน้าที่ที่เกี่ยวข้องกับการจัดการพฤติกรรมของอีเวนต์ (Event Handling) แต่ในความเป็นจริงแล้ว ทั้งสองตัวนี้ทำงานต่างกันอย่างชัดเจน

1. event.preventDefault() คืออะไร?

event.preventDefault() เป็นเมธอดที่ใช้สำหรับป้องกันพฤติกรรมเริ่มต้นขององค์ประกอบ HTML จากการทำงานตามปกติ เช่น การส่งฟอร์ม หรือการเปิดลิงก์

ตัวอย่างการใช้งาน event.preventDefault()

ป้องกันลิงก์จากการนำทางไปยังหน้าอื่น

// เลือก <a> และป้องกันการเปลี่ยนหน้าเมื่อคลิก
const link = document.querySelector("a");
link.addEventListener("click", function(event) {
    event.preventDefault(); // ป้องกันพฤติกรรมเริ่มต้นของลิงก์
    console.log("ลิงก์ถูกคลิก แต่ไม่ได้เปลี่ยนหน้า");
});

ป้องกันฟอร์มจากการส่งข้อมูล

// เลือก <form> และป้องกันการส่งฟอร์ม
const form = document.querySelector("form");
form.addEventListener("submit", function(event) {
    event.preventDefault(); // ป้องกันการส่งฟอร์ม
    console.log("ฟอร์มถูกส่ง แต่ไม่ได้รีเฟรชหน้า");
});

2. event.stopPropagation() คืออะไร?

event.stopPropagation() เป็นเมธอดที่ใช้สำหรับป้องกันเหตุการณ์จากการแพร่กระจายไปยังองค์ประกอบอื่นใน DOM ซึ่งมีผลกับ Event Bubbling และ Event Capturing

ตัวอย่างการใช้งาน event.stopPropagation()

หยุดเหตุการณ์จากการกระจายไปยังพาเรนต์ (Parent Element)

// สมมติว่ามีโครงสร้าง HTML ดังนี้
// <div class="parent">
// <button class="child">Click Me</button>
// </div>

const parent = document.querySelector(".parent");
const child = document.querySelector(".child");

parent.addEventListener("click", function() {
    console.log("Parent ถูกคลิก");
});

child.addEventListener("click", function(event) {
    event.stopPropagation(); // ป้องกัน event จากการส่งไปยัง parent
    console.log("Child ถูกคลิก");
});

ผลลัพธ์:

  • หากคลิกที่ <button class="child">Click Me</button> จะเห็นเฉพาะข้อความ "Child ถูกคลิก" ในคอนโซล
  • หากไม่ได้ใช้ event.stopPropagation(), จะเห็นทั้ง "Child ถูกคลิก" และ "Parent ถูกคลิก"

3. กรณีที่ต้องใช้ทั้ง preventDefault() และ stopPropagation()

บางครั้งเราจำเป็นต้องใช้ทั้งสองคำสั่งร่วมกัน เช่น ในกรณีที่ต้องการป้องกันพฤติกรรมเริ่มต้นของฟอร์ม และต้องการให้เหตุการณ์ไม่ถูกส่งต่อไปยังองค์ประกอบอื่น ๆ

ตัวอย่างการใช้งานร่วมกัน

const form = document.querySelector("form");
form.addEventListener("submit", function(event) {
    event.preventDefault(); // ป้องกันการส่งฟอร์ม
    event.stopPropagation(); // ป้องกันการกระจาย event ไปยังองค์ประกอบอื่น
    console.log("ฟอร์มถูกบล็อกไม่ให้ส่งและหยุดการแพร่กระจายของอีเวนต์");
});

4. สรุปความแตกต่างระหว่าง preventDefault() และ stopPropagation()

คำสั่ง หน้าที่หลัก ใช้เมื่อไหร่?
preventDefault() ป้องกันพฤติกรรมเริ่มต้นขององค์ประกอบ HTML ใช้เมื่อไม่ต้องการให้ลิงก์เปลี่ยนหน้า, ฟอร์มส่งข้อมูล หรือเมนูคลิกขวาแสดงผล
stopPropagation() ป้องกันเหตุการณ์จากการแพร่กระจายใน DOM ใช้เมื่อไม่ต้องการให้ event ถูกส่งต่อไปยังองค์ประกอบพาเรนต์หรืออื่น ๆ

5. ตัวอย่างการนำไปใช้จริงในโปรเจ็กต์

กรณีศึกษา: สร้างเมนูคลิกขวาแบบกำหนดเอง (Custom Context Menu)

สมมติว่าเราต้องการสร้างเมนูคลิกขวาแบบกำหนดเอง และต้องป้องกันเมนูคลิกขวาของเบราว์เซอร์ รวมถึงป้องกัน event bubbling เพื่อไม่ให้เมนูถูกปิดโดยคลิกที่องค์ประกอบอื่น ๆ

const customMenu = document.getElementById("custom-menu");
document.addEventListener("contextmenu", function(event) {
    event.preventDefault(); // ป้องกันเมนูคลิกขวาของเบราว์เซอร์
    customMenu.style.top = `${event.clientY}px`;
    customMenu.style.left = `${event.clientX}px`;
    customMenu.style.display = "block";
});

document.addEventListener("click", function(event) {
if (!customMenu.contains(event.target)) {
    customMenu.style.display = "none";
}
});

customMenu.addEventListener("click", function(event) {
    event.stopPropagation(); // ป้องกันเมนูจากการปิดเมื่อคลิกภายในตัวมันเอง
});

การทำงานของโค้ดนี้

  1. เมื่อคลิกขวาบนหน้าเว็บ เมนูที่กำหนดเองจะแสดงขึ้นมาแทนเมนูปกติของเบราว์เซอร์ (preventDefault())
  2. หากคลิกนอกเมนู เมนูจะถูกซ่อน (click event บน document)
  3. หากคลิกภายในเมนู เมนูจะไม่ถูกซ่อน (stopPropagation())

บทสรุป

  • event.preventDefault() ใช้เพื่อป้องกันพฤติกรรมเริ่มต้นขององค์ประกอบ HTML เช่น ลิงก์และฟอร์ม
  • event.stopPropagation() ใช้เพื่อหยุดการส่งต่อของเหตุการณ์ใน DOM (Event Bubbling และ Capturing)
  • สามารถใช้ร่วมกันได้เพื่อควบคุมพฤติกรรมของอีเวนต์ได้อย่างสมบูรณ์
  • มีประโยชน์ในหลายกรณี เช่น ป้องกันลิงก์เปิดหน้าใหม่, ป้องกันการส่งฟอร์ม, ควบคุม Event Bubbling และสร้าง UI ที่มีการโต้ตอบที่ดีขึ้น

หวังว่าบทความนี้จะช่วยให้เข้าใจความแตกต่างและการใช้งานของ event.preventDefault() และ event.stopPropagation() ได้ดีขึ้น!

0SHAREFacebookLINE it!