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 phiên bản 102) để cải thiện các phương thức đã chứng minh là có vấn đề trong thực tế. intercept()
cho phép nhà phát triển kiểm soát trạng thái sau khi điều hướng, thay thế transitionWhile()
khó sử dụng. Phương thức scroll()
cuộn đến một quảng cáo cố định được chỉ định trong URL, thay thế cho restoreScroll()
không hoạt động trong một số loại thao tác đ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 phương pháp và cách các phương pháp mới khắc phục những vấn đề đó.
NavigateEvent.transitionWhile()
Phương thức NavigateEvent.trasitionWhile()
, được giới thiệu cùng với Navigation API trong Chrome 102, sẽ chặn thao tác điều hướng cho các lượt chuyển đổi phía máy khách trong ứng dụng một trang. Đối số đầu tiên của hàm này là một lời hứa báo hiệu cho trình duyệt và các phần khác của ứng dụng web rằng quá trình tải đã hoàn tất.
Cách này không hiệu quả trong thực tế. Hãy xem xét mẫu lập trình phổ biến sau:
event.transitionWhile((async () => {
doSyncStuff();
await doAsyncStuff();
})());
Mã này tương đương về mặt chức năng với mã bên dưới. Điều này khiến một số phần của thao tác điều hướng chạy trước khi API nhận biết rằng nhà phát triển có ý định chặn thao tác điều hướng.
doSyncStuff();
event.transitionWhile((async () => {
await doAsyncStuff();
})());
Một ví dụ về điều này có thể gây rắc rối cho ứng dụng là logic khôi phục thao tác cuộn, trong đó ứng dụng ghi lại vị trí cuộn sau khi thay đổi DOM, thay vì trước đó.
Những điểm thay đổi
Để thay thế transitionWhile()
, thông số kỹ thuật hiện tại sẽ giới thiệu NavigateEvent.intercept()
. Phương thức mới sẽ nhận một trình xử lý ngoài các thuộc tính focusReset
và scrollRestoration
mà transitionWhile()
hỗ trợ. Trình xử lý mới luôn chạy sau khi các thay đổi điều hướng được xác nhận và các thông tin như vị trí cuộn đã được ghi lại, tránh các vấn đề với transitionWhile()
.
Phương thức transitionWhile()
vẫn hoạt động nhưng không còn được dùng nữa và sẽ bị xoá trong Chrome 108.
Sử dụng intercept()
NavigateEvent.intercept()
có các quy định hạn chế giống như transitionWhile()
, vì không thể gọi trên tất cả các sự kiện điều hướng. Không thể chặn thao tác điều hướng giữa các nguồn gốc cũng như không thể chặn thao tác di chuyển giữa các 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();
}
});
});
NavigateEvent.scroll()
Một thao tác điều hướng như từ đầu trang đến điểm neo (gọi là di chuyển từ /a
sang /a#id
) sẽ do trình duyệt xử lý hoàn toàn ngay cả trong một ứng dụng trang đơn. Tuy nhiên, việc điều hướng đến một điểm neo 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 ứng dụng trang đơn. Ứng dụng phải chặn thao tác điều hướng đến /b#id
bằng NavigateEvent.transitionWhile()
, sau đó gọi NavigateEvent.restoreScroll()
để đưa neo vào chế độ xem. Như đã nêu ở trên, hiện tại, việc này rất khó thực hiện.
Những điểm thay đổi
Trong các ứng dụng trang đơn, giờ đây, bạn có thể kiểm soát việc trình duyệt có xử lý thao tác cuộn đến văn bản liên kết hay không hoặc mã của bạn có xử lý như vậy hay không.
Sử dụng scroll()
Theo mặc định, trình duyệt sẽ cố gắng tự động xử lý thao tác cuộn sau khi trình xử lý 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 hoạt động nhưng không còn đượ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 của API này chứa nhiều thông tin dành riêng cho nhà phát triển web.