ความแตกต่างระหว่าง 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(); // ป้องกันเมนูจากการปิดเมื่อคลิกภายในตัวมันเอง
});
การทำงานของโค้ดนี้
- เมื่อคลิกขวาบนหน้าเว็บ เมนูที่กำหนดเองจะแสดงขึ้นมาแทนเมนูปกติของเบราว์เซอร์ (
preventDefault()
) - หากคลิกนอกเมนู เมนูจะถูกซ่อน (
click
event บนdocument
) - หากคลิกภายในเมนู เมนูจะไม่ถูกซ่อน (
stopPropagation()
)
บทสรุป
event.preventDefault()
ใช้เพื่อป้องกันพฤติกรรมเริ่มต้นขององค์ประกอบ HTML เช่น ลิงก์และฟอร์มevent.stopPropagation()
ใช้เพื่อหยุดการส่งต่อของเหตุการณ์ใน DOM (Event Bubbling และ Capturing)- สามารถใช้ร่วมกันได้เพื่อควบคุมพฤติกรรมของอีเวนต์ได้อย่างสมบูรณ์
- มีประโยชน์ในหลายกรณี เช่น ป้องกันลิงก์เปิดหน้าใหม่, ป้องกันการส่งฟอร์ม, ควบคุม Event Bubbling และสร้าง UI ที่มีการโต้ตอบที่ดีขึ้น
หวังว่าบทความนี้จะช่วยให้เข้าใจความแตกต่างและการใช้งานของ event.preventDefault()
และ event.stopPropagation()
ได้ดีขึ้น!