เหตุการณ์ popstate
ตอบสนองต่อการนำทางย้อนกลับและไปข้างหน้าของเบราว์เซอร์
เหตุการณ์ popstate เป็นบทเรียน HTML Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน HTML Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส HTML Academy มีบทเรียนทั้งหมด 4 บทเรียน
หน้าที่ของเหตุการณ์การเปลี่ยนประวัติ
เหตุการณ์ popstate จะเกิดขึ้นบนหน้าต่างเมื่อผู้ใช้นำทางผ่านประวัติ เช่น ย้อนกลับ ไปข้างหน้า หรือเรียก history.back จาก JavaScript เหตุการณ์นี้ช่วยให้ SPA แสดงผลมุมมองที่ถูกต้องเพื่อตอบสนองต่อการนำทางที่เริ่มจากเบราว์เซอร์
เวลาที่เหตุการณ์นี้เกิดขึ้น
เหตุการณ์ popstate จะเกิดขึ้นเมื่อคลิกปุ่มย้อนกลับหรือไปข้างหน้า เมื่อเรียก history.back(), history.forward() และ history.go(n) เหตุการณ์นี้จะไม่เกิดขึ้นเมื่อเรียก pushState หรือ replaceState ด้วยตนเอง เพราะนั่นเป็นการอัปเดตโดยโปรแกรม และหน้าเว็บก็ทราบการเปลี่ยนแปลงนั้นอยู่แล้ว
window.addEventListener("popstate", (e) => {
console.log("Navigated to", location.pathname, "state:", e.state);
renderPage(location.pathname);
});พร็อพเพอร์ตีสถานะ
พร็อพเพอร์ตี state ของเหตุการณ์จะเก็บออบเจ็กต์สถานะที่คุณส่งให้ pushState หรือ replaceState สำหรับรายการที่กำลังนำทางไป ใช้พร็อพเพอร์ตีนี้เพื่อคืนค่าสถานะของส่วนติดต่อผู้ใช้ เช่น แท็บที่เปิดอยู่หรือตำแหน่งการเลื่อน ซึ่งไม่ได้เก็บไว้ในที่อยู่
อ่านที่อยู่ใหม่
แถบที่อยู่จะอัปเดตเรียบร้อยแล้วเมื่อเหตุการณ์การเปลี่ยนประวัติเกิดขึ้น อ่าน location.pathname, location.search, location.hash เพื่อค้นหาที่อยู่ใหม่ เมื่อนำมารวมกับสถานะแล้ว ข้อมูลเหล่านี้คือข้อมูลทั้งหมดที่จำเป็นต่อการแสดงผลมุมมองปลายทาง
การโหลดหน้าแรก
เหตุการณ์การเปลี่ยนประวัติจะไม่เกิดขึ้นเมื่อโหลดหน้าแรก — จะเกิดขึ้นเฉพาะตอนนำทางเท่านั้น ให้แสดงผลมุมมองแรกจาก location เมื่อเริ่มต้น จากนั้นให้เหตุการณ์นี้จัดการการนำทางครั้งต่อ ๆ ไป หากไม่ทำเช่นนี้ หน้าแรกจะว่างเปล่าเมื่อการย้อนกลับครั้งแรกมาถึง
// Initial render
renderPage(location.pathname);
// Future navigation
window.addEventListener("popstate", () => renderPage(location.pathname));การเปลี่ยนแฮชเทียบกับการเปลี่ยนประวัติ
สำหรับการกำหนดเส้นทางด้วยแฮชล้วน ๆ เช่นที่อยู่รูปแบบ /#/about เหตุการณ์ hashchange จะเกิดขึ้นเมื่อแฮชเปลี่ยน เหตุการณ์การเปลี่ยนประวัติจะเกิดขึ้นกับการเปลี่ยนพาธด้วย SPA สมัยใหม่ใช้ History API และเหตุการณ์การเปลี่ยนประวัติ ส่วนการกำหนดเส้นทางด้วยแฮชเป็นแนวทางเดิม
การดักจับการคลิก
หากต้องการให้การคลิก <a> ปกติเรียกใช้การนำทางฝั่งไคลเอนต์ ให้ดักจับการคลิก เรียก preventDefault แล้วเรียก pushState ร่วมกับ renderPage ตรวจสอบปุ่มปรับแต่ง เช่น การคลิกพร้อมปุ่มลัดเพื่อเปิดแท็บใหม่ และปล่อยให้การทำงานเริ่มต้นจัดการกรณีเหล่านั้นตามปกติ
document.addEventListener("click", (e) => {
const a = e.target.closest("a");
if (!a || a.target || e.metaKey || e.ctrlKey) return;
e.preventDefault();
history.pushState(null, "", a.href);
renderPage(location.pathname);
});คืนค่าตำแหน่งการเลื่อน
เบราว์เซอร์จะพยายามคืนค่าตำแหน่งการเลื่อนโดยอัตโนมัติเมื่อย้อนกลับ แต่การทำงานนี้ไม่น่าเชื่อถือใน SPA เพราะเนื้อหาถูกแสดงผลแบบไม่พร้อมกัน ให้บันทึกตำแหน่งการเลื่อนไว้ในสถานะของ pushState และคืนค่าในเหตุการณ์การเปลี่ยนประวัติด้วย window.scrollTo(0, e.state?.scroll ?? 0)
ข้อควรระวังในการแสดงผลแบบไม่พร้อมกัน
หาก renderPage ดึงข้อมูลแบบไม่พร้อมกัน ที่อยู่จะอัปเดตก่อนที่เนื้อหาจะมาถึง ให้แสดงสถานะกำลังโหลด แล้วจึงแสดงผล หลีกเลี่ยงสภาวะแข่งขันที่ผู้ใช้กดย้อนกลับระหว่างการดึงข้อมูล และผลลัพธ์จากคำขอที่ยกเลิกแล้วเขียนทับมุมมองใหม่
ตัวจัดการเส้นทางของเฟรมเวิร์ก
ตัวจัดการเส้นทางของรีแอ็กต์ ตัวจัดการเส้นทางของวี และตัวจัดการเส้นทางของ SvelteKit ล้วนห่อหุ้ม History API กับเหตุการณ์การเปลี่ยนประวัติไว้ แม้ไม่ใช้เฟรมเวิร์ก พื้นฐานก็ยังเหมือนเดิม — รับฟังเหตุการณ์การเปลี่ยนประวัติ ดักจับลิงก์ และเรียก pushState เมื่อเรื่องค่าใช้จ่ายในการทำงานมีความสำคัญ คุณสามารถสร้างตัวจัดการเส้นทางของตนเองด้วย JavaScript แบบไม่ใช้เฟรมเวิร์กได้ในประมาณ 50 บรรทัด
หลุมพรางที่พบบ่อย: หน่วยความจำรั่ว
การตั้งค่าของแต่ละมุมมองอาจเพิ่มตัวรับฟังเหตุการณ์และตัวจับเวลา หากไม่มีการรื้อการตั้งค่าอย่างชัดเจนเมื่อมุมมองเปลี่ยน เช่น ในเหตุการณ์การเปลี่ยนประวัติหรือในตัวห่อหุ้ม pushState ตัวรับฟังเหล่านี้จะสะสมและทำให้ประสิทธิภาพลดลงตามเวลา ให้ติดตามการสมัครรับข้อมูลของแต่ละมุมมองด้วย AbortController และยกเลิกทั้งหมดเมื่อมุมมองเปลี่ยน
ตรวจสอบความเข้าใจ
เหตุใดเหตุการณ์การเปลี่ยนประวัติจึงไม่เกิดขึ้นเมื่อคุณเรียก history.pushState ด้วยตนเอง
สรุป
เหตุการณ์การเปลี่ยนประวัติจะเกิดขึ้นเมื่อผู้ใช้ย้อนกลับหรือไปข้างหน้าผ่านเบราว์เซอร์ ทำให้เข้าถึงสถานะที่บันทึกไว้และที่อยู่ใหม่ได้ เหตุการณ์นี้จะไม่เกิดขึ้นเมื่อเรียก pushState หรือ replaceState เพราะโค้ดของคุณทราบการเปลี่ยนแปลงอยู่แล้ว และจะไม่เกิดขึ้นเมื่อโหลดหน้าแรก เพราะต้องแสดงผลด้วยตนเอง ให้ดักจับการคลิกลิงก์สำหรับการนำทางใน SPA บันทึกตำแหน่งการเลื่อนไว้ในสถานะ และรื้อการตั้งค่าตัวรับฟังเมื่อมุมมองเปลี่ยนเพื่อป้องกันการรั่วไหล
คำถามที่พบบ่อย
บทเรียน “เหตุการณ์ popstate” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เหตุการณ์ popstate” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส HTML Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส HTML Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เหตุการณ์ popstate”
ตอบสนองต่อการนำทางย้อนกลับและไปข้างหน้าของเบราว์เซอร์ คุณปฏิบัติ HTML Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน HTML Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน HTML Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “เหตุการณ์ popstate” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน HTML Academy นี้ได้ไหม
ได้ บทเรียน HTML Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- pushState และ replaceState
- เหตุการณ์ popstate
- การกำหนดเส้นทางด้วยแฮชเทียบกับพาธ
- Navigation API ในเบราว์เซอร์สมัยใหม่