การเปลี่ยนแปลงของ NavigationEvent ใน Chrome 105

Joe Medley
Joe Medley

Chrome 105 เปิดตัวเมธอดใหม่ 2 รายการใน NavigateEvent ของ Navigation API (เปิดตัวใน 102) เพื่อปรับปรุงเมธอดที่พิสูจน์แล้วว่ามีปัญหาในทางปฏิบัติ intercept() ซึ่งช่วยให้นักพัฒนาแอปควบคุมสถานะหลังจากการนําทางได้ จะเข้ามาแทนที่ transitionWhile() ซึ่งใช้งานยาก วิธีการ scroll() ซึ่งเลื่อนไปยังจุดยึดที่ระบุใน URL จะแทนที่ restoreScroll() ที่ไม่ทำงานกับการนําทางบางประเภท

บทความนี้จะอธิบายปัญหาของทั้ง 2 วิธีและวิธีที่วิธีการใหม่แก้ไขปัญหาเหล่านั้น

เมธอด 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();
    }
  });
});

การนำทาง เช่น การนำทางจากด้านบนของหน้าไปยังจุดยึด (เรียกการย้ายจาก /a ไปยัง /a#id) นั้นจัดการโดยเบราว์เซอร์ทั้งหมดแม้ในแอปแบบหน้าเดียว แต่การนำทางไปยังจุดยึดใน "หน้า" อื่น (/a ไปยัง /b#id) ซึ่งง่ายสำหรับแอปแบบหลายหน้าจะซับซ้อนกว่าสำหรับแอปแบบหน้าเดียว แอปต้องขัดจังหวะการนำทางไปยัง /b#id โดยใช้ NavigateEvent.transitionWhile() จากนั้นเรียกใช้ NavigateEvent.restoreScroll() เพื่อแสดงโฆษณา 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 นี้มีข้อมูลมากมายสำหรับนักพัฒนาเว็บโดยเฉพาะ

รูปภาพโดย Tim Gouw ใน Unsplash