เบราว์เซอร์มีการโต้ตอบและพฤติกรรมเริ่มต้นสำหรับเหตุการณ์ต่างๆ
ตัวอย่างเช่น เมื่อผู้ใช้คลิกปุ่ม "ส่ง" บนแบบฟอร์ม แบบฟอร์มจะถูกส่งไปยัง URL โดยค่าเริ่มต้น
เมื่อมีการคลิกลูกขององค์ประกอบ เหตุการณ์การคลิกจะเกิดขึ้นกับองค์ประกอบนั้นด้วยเพราะเป็นคอนเทนเนอร์หลัก
ในบางกรณี คุณอาจต้องการแทนที่ค่าเริ่มต้นเหล่านี้ ในบทความนี้เราจะมาเรียนรู้ว่า event.preventDefault()
และ event.stopPropagation()
เมธอดและวิธีใช้เพื่อยกเลิกการดำเนินการเริ่มต้นบางอย่างที่เกิดขึ้นในเบราว์เซอร์
event.preventDefault()
วิธีนี้จะป้องกันการกระทำเริ่มต้นที่เบราว์เซอร์ทำเมื่อมีการทริกเกอร์เหตุการณ์
ต่อไปนี้คือตัวอย่างการดำเนินการเริ่มต้นบนหน้าเว็บและวิธีแทนที่ด้วย event.preventDefault()
.
วิธีการแทนที่การส่งแบบฟอร์มเริ่มต้น
เมื่อผู้ใช้ส่งแบบฟอร์ม (คลิกปุ่มส่ง) การดำเนินการเริ่มต้นของแบบฟอร์มคือการส่งข้อมูลของแบบฟอร์มไปยัง URL ที่ประมวลผลข้อมูล
องค์ประกอบแบบฟอร์มมี action
และ method
แอตทริบิวต์ที่ระบุ URL ที่จะส่งแบบฟอร์มและประเภทคำขอ (get
, post
เป็นต้น) ตามลำดับ
หากไม่มีการระบุแอตทริบิวต์เหล่านี้ URL เริ่มต้นจะเป็น URL ปัจจุบันที่ส่งแบบฟอร์ม และวิธีการคือ get
.
ตัวอย่างเช่น รหัสนี้:
<form>
<input name="email" />
<input name="password" />
<input type="submit" />
</form>
ผลิตหน้านี้:
เมื่อส่งแบบฟอร์มที่มีอินพุต "dillion" และ "password" คุณจะเห็น get
ส่งคำขอไปที่ 127.0.0.1:5500/index.html
แบบนี้:
การดำเนินการนี้เป็นวิธีที่เบราว์เซอร์จัดการแบบฟอร์มโดยค่าเริ่มต้น
แต่คุณอาจต้องการทำสิ่งต่างๆ เพิ่มเติมกับข้อมูลก่อนที่จะส่งคำขอ ซึ่งเป็นเรื่องปกติโดยเฉพาะอย่างยิ่งในแนวทางการจัดการแบบฟอร์มในปัจจุบัน
คุณอาจต้องการตรวจสอบข้อมูล ตรวจสอบข้อมูล ประมวลผล กำหนดค่าส่วนหัว และอื่นๆ ก่อนส่งคำขอไปยัง URL
ในสถานการณ์เหล่านี้ คุณจะต้องป้องกันไม่ให้มีการดำเนินการเริ่มต้นของฟอร์ม วิธีการ:
<form id='form'>
...
</form>
const form = document.getElementById('form')
form.addEventListener('submit', (event) => {
event.preventDefault()
// process data and submit a request manually
})
ด้วยวิธีนี้ การส่งแบบฟอร์มอยู่ในมือคุณ
วิธีการแทนที่การทำงานเริ่มต้นเมื่อคลิกลิงก์
เมื่อคุณคลิกลิงก์ (แท็กสมอ a
ด้วย href
แอตทริบิวต์) การดำเนินการเริ่มต้นคือการนำทางบนเบราว์เซอร์ไปยังลิงก์ที่คลิก
จะทำอย่างไรถ้าคุณต้องการสกัดกั้นการกระทำนั้นและอาจทำอะไรบางอย่างก่อนการนำทาง ตัวอย่างเช่น การตรวจสอบว่าผู้ใช้มีสิทธิ์เข้าถึงหน้าที่พวกเขาต้องการนำทางไป คุณต้องทำดังนี้:
<a id="link" href="https://google.com">Google</a>
const link = document.getElementById("link")
link.addEventListener("click", event => {
event.preventDefault()
// do something and navigate
})
คุณสามารถทดสอบได้ เมื่อคุณคลิกลิงก์ "Google" จะไม่มีการนำทางเกิดขึ้น เนื่องจากคุณได้ป้องกันการดำเนินการการนำทางเริ่มต้น ตอนนี้ คุณต้องจัดการการนำทางด้วยตัวเอง
event.stopPropagation()
การขยายพันธุ์คือการแพร่กระจายบางสิ่งบางอย่างในกรณีนี้คือเหตุการณ์ stopPropagation
เมธอดถูกใช้เพื่อป้องกันการแพร่กระจายของเหตุการณ์เมื่อมีการทริกเกอร์เหตุการณ์บนองค์ประกอบ
ใน JavaScript เมื่อคุณทริกเกอร์เหตุการณ์บนองค์ประกอบหนึ่ง มันจะสร้างฟองขึ้นต้นไม้ไปยังผู้ปกครองและบรรพบุรุษขององค์ประกอบนั้น โดยพื้นฐานแล้ว องค์ประกอบที่มีเหตุการณ์คือ "ภายใน" คอนเทนเนอร์ของพาเรนต์ ดังนั้นองค์ประกอบหลักจึงได้รับเหตุการณ์ด้วย
ฉันจะใช้ตัวอย่างเพื่ออธิบายให้ดีกว่านี้
การคลิกลูกขององค์ประกอบ
สมมติว่าคุณมีองค์ประกอบดังต่อไปนี้:
<div>
<button>Click me</button>
</div>
เมื่อคุณคลิกที่ button
คุณกำลังคลิกที่ div
คอนเทนเนอร์เพราะปุ่มอยู่ในคอนเทนเนอร์ ตรรกะนี้หมายความว่าเหตุการณ์การคลิกแพร่กระจายจากปุ่มไปยังคอนเทนเนอร์ และเหตุการณ์ยังคงแพร่กระจายไปยังปู่ย่าตายายทั้งหมดจนกว่าจะถึงรูท
เพื่อตรวจสอบสิ่งนี้ ฉันจะอธิบายวิธีการทำงานกับรหัสนี้:
<div id="div">
<button id="button">Click me</button>
</div>
const div = document.getElementById('div')
const button = document.getElementById('button')
button.addEventListener('click', () => {
console.log('button clicked')
})
div.addEventListener('click', () => {
console.log('div container clicked')
})
เมื่อคุณพยายามเรียกใช้สิ่งนี้บนเบราว์เซอร์ของคุณและคลิกปุ่ม คุณจะได้ผลลัพธ์นี้:
div
คอนเทนเนอร์ยังได้รับเหตุการณ์การคลิกด้วย ดังนั้นจึงเรียกฟังก์ชันเรียกกลับการคลิกด้วย
การเผยแพร่เหตุการณ์เป็นพฤติกรรมเริ่มต้นของเหตุการณ์และองค์ประกอบ แต่ในบางกรณี คุณอาจไม่ต้องการพฤติกรรมบางอย่าง ในบรรดาตัวอย่างมากมาย นี่คือตัวอย่างหนึ่ง
นี่คือป๊อปอัปข้อความใหม่ของ Gmail:
ที่ด้านบน คุณมีปุ่มการทำงานสามปุ่ม หนึ่งย่อขนาดป๊อปอัป หนึ่งทำให้ป๊อปอัปเต็มหน้าจอ และอีกอันหนึ่งปิดป๊อปอัป
แต่แถบด้านบนที่มีข้อความ "ข้อความใหม่" มีตัวจัดการการคลิกด้วย ดังนั้นเมื่อคลิกแล้ว จะย่อขนาดป๊อปอัปให้เล็กสุด:
สิ่งหนึ่งที่คุณต้องการหลีกเลี่ยงที่นี่คือ เมื่อคลิกปุ่มใดๆ คุณไม่ต้องการให้เหตุการณ์การคลิกแพร่กระจายไปที่แถบด้านบนและเรียกใช้ฟังก์ชันสำหรับเหตุการณ์นั้นด้วย สิ่งที่ฉันหมายถึงคือ ตัวอย่างเช่น เมื่อคลิกปุ่มปิด คุณไม่ต้องการให้แถบด้านบนย่อให้เล็กสุดด้วย
ในกรณีเช่นนี้ คุณต้องการหยุดการขยายพันธุ์
สมมติว่าป๊อปอัปสร้างขึ้นดังนี้:
<div id='top-bar'>
<!-- The Message Element -->
<!-- The Buttons -->
</div>
const topBar = document.getElementById('top-bar')
const closeButton = document.getElementById('close-btn')
topBar.addEventListener('click', () => {
// minimize or maximize popup
})
closeButton.addEventListener('click', () => {
// close popup
})
คุณจะต้องเพิ่ม stopPropagation
วิธีการฟังของปุ่ม เพื่อหลีกเลี่ยงการแพร่กระจายเหตุการณ์ไปที่แถบด้านบน โดยคุณจะต้องอัปเดตตัวฟังของปุ่มเป็น:
closeButton.addEventListener('click', (event) => {
event.stopPropagation()
// close popup
})
ด้วยสิ่งนี้ แถบด้านบนจะได้รับเฉพาะเหตุการณ์การคลิกเมื่อมีการคลิกโดยตรงเท่านั้น
สรุปผล
ความแตกต่างระหว่าง event.preventDefault()
และ event.stopPropagation()
คือก่อนหน้านี้ป้องกันการกระทำเริ่มต้นที่ทำโดยเบราว์เซอร์ในขณะที่อย่างหลังป้องกันพฤติกรรมเริ่มต้นของเหตุการณ์ - การแพร่กระจายขึ้นต้นไม้
การกระทำและพฤติกรรมเริ่มต้นเหล่านี้ไม่ใช่ข้อผิดพลาด และคุณไม่ต้องกังวลเกี่ยวกับสิ่งเหล่านี้ขณะเขียนโค้ด แต่มีบางสถานการณ์ที่คุณต้องการแทนที่ดังที่เราได้เห็นในตัวอย่างในบทความนี้