Các thay đổi đối với navigationEvent trong Chrome 105

Liên khúc Joe
Joe Medley

Chrome 105 giới thiệu hai phương thức mới trên NavigateEvent của Navigation API (được giới thiệu trong năm 102) để cải thiện các phương thức đã được chứng minh là có vấn đề trong thực tế. intercept() (cho phép các nhà phát triển kiểm soát trạng thái sau khi điều hướng) sẽ thay thế transitionWhile() – một phương thức rất khó sử dụng. Phương thức scroll() cuộn đến một liên kết được chỉ định trong URL sẽ thay thế restoreScroll() (không hoạt động với mọi loại điều hướng).

Trong bài viết này, tôi sẽ giải thích các vấn đề với cả hai vấn đề này và cách các phương pháp mới khắc phục những vấn đề đó.

Phương thức NavigateEvent.trasitionWhile() (được giới thiệu từ Navigation API trong Chrome 102) sẽ chặn tính năng điều hướng đối với quá trình chuyển đổi phía máy khách trong các ứng dụng trang đơn. Đối số đầu tiên của mã là lời hứa sẽ báo hiệu cho trình duyệt và các phần khác của ứng dụng web rằng trình duyệt đã hoàn tất.

Tính năng này hoạt động kém hiệu quả trong thực tế. Hãy xem xét mẫu lập trình phổ biến này:

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

Mã này có chức năng tương đương với mã dưới đây. Điều này khiến một số phần điều hướng chạy trước khi API biết rằng nhà phát triển có ý định chặn quá trình điều hướng.

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

Một ví dụ về trường hợp này có thể làm hỏng ứng dụng là trong logic khôi phục thao tác cuộn, trong đó logic khôi phục thao tác cuộn ghi lại các vị trí cuộn sau khi DOM thay đổi, thay vì trước đó.

Những điểm thay đổi

Để thay thế transitionWhile(), thông số kỹ thuật hiện tại ra mắt NavigateEvent.intercept(). Phương thức mới này sẽ sử dụng một trình xử lý cùng với các thuộc tính focusResetscrollRestorationtransitionWhile() hỗ trợ. Trình xử lý mới luôn chạy sau khi thực hiện thao tác điều hướng và ghi lại những nội dung như vị trí cuộn, giúp tránh các vấn đề với transitionWhile().

Phương thức transitionWhile() vẫn dùng được, nhưng không được dùng nữa và sẽ bị xoá trong Chrome 108.

Dùng phương thức Chặn()

NavigateEvent.intercept() có cùng các hạn chế với transitionWhile(), vì trong đó không thể gọi được trên tất cả các sự kiện điều hướng. Không thể chặn hoạt động điều hướng trên nhiều nguồn gốc và hoạt động truyền tải dữ liệu giữa nhiều tài liệu. Thao tác này sẽ gửi một DOMException thuộc loại "SecurityError".

Để sử dụng intercept(), bạn chỉ cần truyền trình xử lý tuỳ chỉnh khi gọi trình xử lý đó.

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

Trình duyệt sẽ xử lý hoàn toàn các thao tác điều hướng, chẳng hạn như di chuyển từ đầu trang đến vị trí liên kết (gọi là di chuyển từ /a sang /a#id) ngay cả trong một ứng dụng trang đơn. Tuy nhiên, việc điều hướng đến một quảng cáo cố định trên một "trang" khác (/a đến /b#id) (đơn giản đối với ứng dụng nhiều trang) lại phức tạp hơn đối với các ứng dụng một trang. Ứng dụng phải chặn quá trình điều hướng đến /b#id bằng NavigateEvent.transitionWhile(), sau đó gọi NavigateEvent.restoreScroll() để đưa điểm neo vào khung hiển thị. Như đã đề cập ở trên, điều này hiện rất khó thực hiện.

Những điểm thay đổi

Giờ đây, trong các ứng dụng trang đơn, bạn có thể kiểm soát việc trình duyệt có xử lý việc cuộn đến một điểm neo hay mã của bạn có xử lý việc cuộn đến một điểm neo hay không.

Sử dụng scroll()

Theo mặc định, trình duyệt sẽ cố gắng xử lý cuộn tự động, sau khi phương thức giao tiếp chặn đã hoàn tất. Nếu bạn muốn tự xử lý thao tác cuộn, hãy đặt scroll thành "manual", sau đó gọi NavigateEvent.scroll() khi trình duyệt cố gắng đặt vị trí cuộn.

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

Phương thức restoreScroll() vẫn dùng được, nhưng không được dùng nữa và sẽ bị xoá trong Chrome 108.

Kết luận

Chúng tôi hy vọng sẽ sớm cập nhật bài viết về Navigation API. Trong thời gian chờ đợi, thông số kỹ thuật cho API này chứa nhiều thông tin dành riêng cho nhà phát triển web.

Ảnh chụp của Tim Gouw trên Unsplash