Chrome 105 นำเสนอ 2 วิธีการใหม่ใน NavigateEvent
ของ Navigation API (เปิดตัวเมื่อ 102) เพื่อปรับปรุงเมธอดที่พิสูจน์แล้วว่าก่อให้เกิดปัญหาในทางปฏิบัติ intercept()
ซึ่งช่วยให้นักพัฒนาซอฟต์แวร์ควบคุมสถานะตามการนำทางได้ ซึ่งจะแทนที่ transitionWhile()
ซึ่งพิสูจน์แล้วว่าใช้งานยาก เมธอด scroll()
ซึ่งเลื่อนไปยังแท็ก Anchor ที่ระบุไว้ใน URL จะแทนที่ restoreScroll()
ซึ่งใช้ไม่ได้กับการนำทางทุกประเภท
ในบทความนี้ เราจะอธิบายปัญหาของทั้ง 2 อย่างและวิธีที่วิธีการใหม่จะช่วยแก้ปัญหาเหล่านั้น
NavigateEvent.transitionWhile()
เมธอด NavigateEvent.trasitionWhile()
ที่มาพร้อมกับ Navigation API ใน Chrome 102 จะขัดขวางการนำทางสำหรับการเปลี่ยนฝั่งไคลเอ็นต์ในแอปที่มีหน้าเดียว อาร์กิวเมนต์แรกเป็นสัญญาณที่บอกเบราว์เซอร์และส่วนอื่นๆ ของเว็บแอปพลิเคชันว่าเสร็จสิ้น
วิธีนี้ได้ผลในทางปฏิบัติไม่ดี ลองพิจารณารูปแบบการเขียนโค้ดทั่วไปนี้
event.transitionWhile((async () => {
doSyncStuff();
await doAsyncStuff();
})());
ซึ่งมีฟังก์ชันการทำงานเทียบเท่ากับโค้ดด้านล่าง เนื่องจากจะทำให้การนำทางบางส่วนทำงานก่อนที่ API จะทราบว่านักพัฒนาซอฟต์แวร์ตั้งใจที่จะสกัดกั้นการนำทางไว้
doSyncStuff();
event.transitionWhile((async () => {
await doAsyncStuff();
})());
ตัวอย่างหนึ่งที่ทำให้แอปสับสนคือในตรรกะการกู้คืนการเลื่อนที่แอปจะบันทึกตำแหน่งการเลื่อนหลังจากการเปลี่ยนแปลง DOM ไม่ใช่ก่อนหน้า
มีอะไรเปลี่ยนแปลงบ้าง
ข้อกำหนดปัจจุบันแนะนำให้ใช้ NavigateEvent.intercept()
เพื่อแทนที่ transitionWhile()
เมธอดใหม่จะใช้ตัวแฮนเดิลนอกเหนือจากพร็อพเพอร์ตี้ focusReset
และ scrollRestoration
ที่ transitionWhile()
รองรับ ตัวแฮนเดิลใหม่จะทำงานเสมอหลังจากที่คอมมิตการนำทางแล้ว และสิ่งต่างๆ เช่น มีการจับภาพตำแหน่งการเลื่อนแล้ว เพื่อหลีกเลี่ยงปัญหาที่เกิดขึ้นกับ transitionWhile()
เมธอด transitionWhile()
ยังคงใช้งานได้อยู่ แต่เลิกใช้งานไปแล้วและจะนำออกใน Chrome 108
การใช้ Intercept()
NavigateEvent.intercept()
มีข้อจำกัดเช่นเดียวกับ transitionWhile()
เนื่องจากไม่สามารถเรียกเหตุการณ์การนำทางทั้งหมด การนำทางข้ามต้นทางไม่สามารถดักจับได้ และการข้ามเอกสารก็ทำไม่ได้ การดำเนินการนี้จะแสดง DOMException
ประเภท "SecurityError"
หากต้องการใช้ intercept()
เพียงส่งตัวแฮนเดิลที่กำหนดเองเมื่อเรียกใช้
navigation.addEventListener("navigate", event => {
event.intercept({
async handler() {
doSyncStuff();
await doAsyncStuff();
}
});
});
NavigateEvent.scroll()
การไปยังส่วนต่างๆ เช่น การนำทางจากด้านบนของหน้าไปยังโฆษณา Anchor (เรียกว่าการย้ายจาก /a
ไปยัง /a#id
) จะได้รับการจัดการโดยเบราว์เซอร์โดยสมบูรณ์แม้ในแอปที่มีหน้าเดียว แต่การไปยังแท็ก Anchor ใน "หน้าเว็บ" อื่น (/a
ถึง /b#id
) ซึ่งใช้งานง่ายสำหรับแอปที่มีหลายหน้า จะซับซ้อนกว่าสำหรับแอปแบบหน้าเดียว แอปต้องสกัดกั้นการนำทางไปยัง /b#id
โดยใช้ NavigateEvent.transitionWhile()
จากนั้นเรียกใช้ NavigateEvent.restoreScroll()
เพื่อนำ Anchor มาดูด้วย ดังที่กล่าวไว้ข้างต้น การดำเนินการดังกล่าวเป็นเรื่องยากในขณะนี้
มีอะไรเปลี่ยนแปลงบ้าง
ในแอปที่มีหน้าเดียว ตอนนี้คุณสามารถควบคุมได้ว่าจะให้เบราว์เซอร์จัดการการเลื่อนไปยังแท็ก Anchor หรือให้โค้ดของคุณทำงานหรือไม่
การใช้ Scroll()
โดยค่าเริ่มต้น เบราว์เซอร์จะพยายามจัดการกับการเลื่อนโดยอัตโนมัติ เมื่อตัวแฮนเดิลปลายทางทำงานจนครบ หากต้องการจัดการการเลื่อนด้วยตนเอง ให้ตั้งค่า scroll
เป็น "manual"
จากนั้นเรียก NavigateEvent.scroll()
เมื่อเบราว์เซอร์ควรพยายามตั้งค่าตำแหน่งการเลื่อน
navigation.addEventListener("manual", event => {
scroll: "manual",
event.intercept({
async handler() {
doSyncStuff();
// Handle scrolling earlier than by default:
event.scroll();
await doAsyncStuff();
}
});
});
เมธอด restoreScroll()
ยังคงใช้งานได้อยู่ แต่เลิกใช้งานไปแล้วและจะนำออกใน Chrome 108
บทสรุป
เราหวังว่าจะได้อัปเดตบทความเกี่ยวกับ Navigation API ในเร็วๆ นี้ ในระหว่างนี้ ข้อกำหนดของ API นี้มีข้อมูลมากมายสำหรับนักพัฒนาเว็บโดยเฉพาะ