Chuyển đổi chế độ xem cho ứng dụng một trang

Một mẫu phổ biến cho các trang web là sử dụng JavaScript để thay thế nội dung trên một trang một cách linh hoạt mà không cần tải một tài liệu HTML mới, đầy đủ. Đây được gọi là Ứng dụng trang đơn (SPA). Hiệu ứng chuyển đổi chế độ xem giúp bạn thể hiện tính liên tục hoặc ngữ cảnh giữa các trang trong SPA.

Hiệu ứng chuyển đổi toàn trang

Khi người dùng chuyển đến một khung hiển thị mới trong SPA, khung sẽ thay thế DOM bằng nội dung mới. Thao tác này chỉ làm cho nội dung xuất hiện, nhưng nếu bạn muốn cung cấp một hiệu ứng chuyển đổi giữa nội dung hiện tại và nội dung mới thì sao?

Hiệu ứng chuyển cảnh thường cho thấy cả khung hình cũ và mới cùng lúc, ví dụ: làm mờ khung hình cũ trong khi làm rõ khung hình mới. Vì nội dung hiện có sẽ bị thay thế, nên đây là một thách thức trước khi có hiệu ứng chuyển đổi chế độ xem.

Để sử dụng hiệu ứng chuyển đổi chế độ xem, bạn sẽ cần bao bọc logic để thay đổi DOM trong một lệnh gọi lại. Đối với những ví dụ này, chúng ta có một phương thức triển khai bộ định tuyến cơ bản do một thành phần web có tên là MyRouter cung cấp. Cách bạn bật hiệu ứng chuyển đổi chế độ xem sẽ tuỳ thuộc vào bộ định tuyến và khung mà bạn đang sử dụng.

document.startViewTransition(() => updateTheDOMSomehow());

Thao tác này cho phép chuyển đổi mặc định, làm mờ chế độ xem cũ trong khi làm mờ chế độ xem mới.

Điều gì đang xảy ra ở đây? Khi bạn gọi document.startViewTransition(), trình duyệt sẽ chụp nhanh chế độ xem cũ. Sau đó, hàm này sẽ gọi hàm gọi lại mà bạn truyền, hàm này sẽ cập nhật DOM thành khung hiển thị mới (nhưng chưa hiển thị). Khi hàm callback hoàn tất, trình duyệt sẽ bắt đầu chuyển sang nội dung mới.

// Fallback for browsers that don't support this API:
if (!document.startViewTransition) {
  updateTheDOMSomehow();
  return;
} else {
  // With a View Transition:
  document.startViewTransition(() => updateTheDOMSomehow());
}

Tuỳ chỉnh hiệu ứng chuyển đổi

Như bạn thấy trong ví dụ trước, View Transition mặc định sẽ làm mờ thành phần hiển thị cũ trong khi làm mờ thành phần hiển thị mới. Bạn có thể tuỳ chỉnh hiệu ứng chuyển đổi cho phù hợp hơn với kiểu trang web của mình bằng cách tạo kiểu cho các phần tử giả do hiệu ứng chuyển đổi chế độ xem tạo ra.

Bạn có thể chỉ định hiệu ứng chuyển đổi khi rời khỏi bằng ::view-transition-old() và hiệu ứng chuyển đổi khi tham gia bằng ::view-transition-new(). Bạn cũng có thể chỉ định giá trị cho cả hai bằng ::view-transition-group().

Trong ví dụ này, khung hiển thị cũ sẽ chuyển đổi ra ngoài bằng hiệu ứng chuyển đổi slide-out-to-left và khung hiển thị mới sẽ chuyển đổi vào trong bằng hiệu ứng chuyển đổi slide-in-from-right. Cả hai đều có thời lượng là 200 mili giây.

::view-transition-group(root){
  animation-duration: 200ms;
}

::view-transition-old(root) {
  animation-name: slide-out-to-left;
}

::view-transition-new(root) {
  animation-name: slide-in-from-right;
}

Các hiệu ứng chuyển đổi khác nhau dựa trên ngữ cảnh

Bạn có thể muốn có các hiệu ứng chuyển đổi khác nhau tuỳ thuộc vào việc người dùng đang làm gì. Ví dụ: nếu thao tác nhấp vào một đường liên kết trên trang chủ sẽ trượt khung hiển thị mới vào từ bên phải, thì bạn có thể mong đợi thao tác nhấp vào một đường liên kết để quay lại trang chủ sẽ trượt khung hiển thị trang chủ vào từ bên trái.

Bạn có thể chỉ định nhiều ảnh động bằng cách sử dụng lớp giả :active-view-transition-type().

html:active-view-transition-type(forwards) {
  &::view-transition-old(root) {
    animation-name: slide-out-to-left;
  }

  &::view-transition-new(root) {
    animation-name: slide-in-from-right;
  }
}

Sau đó, bạn có thể chọn loại hiệu ứng chuyển đổi chế độ xem cần dùng khi gọi document.startViewTransition().

const direction = next === 'home' ? 'backwards' : 'forwards';

document.startViewTransition({
  update: updateTheDOMSomehow,
  types: [direction],
});

Chuyển đổi các phần tử cụ thể

Cho đến nay, bạn chỉ áp dụng hiệu ứng chuyển đổi cho phần tử gốc để chuyển đổi toàn bộ khung hiển thị. Tuy nhiên, bạn cũng có thể sử dụng hiệu ứng chuyển đổi khung hiển thị để tạo ảnh động cho các phần cụ thể trên trang.

Ví dụ: bạn có thể có nội dung ở chế độ xem cũ trùng khớp với nội dung ở chế độ xem mới. Đây có thể là tiêu đề của nội dung hoặc hình ảnh. Thậm chí, đó có thể là một hình thu nhỏ trong chế độ xem cũ và một video trong chế độ xem mới.

Trước tiên, bạn cần chỉ định những phần tử cần chuyển đổi bằng cách sử dụng thuộc tính view-transition-name. Để các hiệu ứng chuyển đổi chế độ xem hoạt động, đối với mỗi view-transition-name, cần có chính xác một phần tử trước khi bạn gọi document.startViewTransition() và chính xác một phần tử sau khi lệnh gọi lại trong document.startViewTransition() hoàn tất.

Trong ví dụ này, có một trình phát nhạc hiển thị ảnh bìa đĩa nhạc, tiêu đề và nghệ sĩ. Một chế độ xem thay thế cho thấy cùng một nội dung được sắp xếp lại, kèm theo lời bài hát.

Trong ví dụ trước, có chính xác một phần tử chuyển đổi trong khung hiển thị cũ và mới, và các phần tử này thậm chí còn dùng chung bộ chọn. Các phần tử được chuyển đổi sẽ xuất hiện để di chuyển giữa kích thước và vị trí của chúng. Các phần không chuyển đổi của khung hiển thị sẽ mờ dần.

Hãy xem một ví dụ phức tạp hơn. Ví dụ: trang chủ của một blog có thể hiển thị tiêu đề và hình ảnh cho mỗi bài đăng, đồng thời những thông tin này cũng xuất hiện trong chế độ xem toàn trang của một bài đăng trên blog. Khi chuyển từ trang chủ đến một bài đăng cụ thể, bạn có thể muốn bài đăng đó xuất hiện như thể tiêu đề và hình ảnh chuyển sang vị trí mới để cung cấp bối cảnh.

Để thực hiện việc này cho tiêu đề, bạn cần có một view-transition-name trên phần tử tiêu đề là duy nhất trong khung hiển thị cũ, được chia sẻ với phần tử tiêu đề trong khung hiển thị mới và là duy nhất trên khung hiển thị mới. Đây là một thách thức, vì trang chủ có nhiều tiêu đề và hình ảnh, đồng thời bạn không biết người dùng sẽ nhấp vào tiêu đề và hình ảnh nào.

Bạn có 2 lựa chọn để giải quyết vấn đề này. Bạn có thể chọn thêm một view-transition-name riêng biệt cho mỗi bài đăng trên trang chủ, sau đó so khớp tên đó với mỗi bài đăng trên trang đầy đủ. Bạn có thể tạo những đường liên kết này bằng mã nhận dạng của bài đăng. Lựa chọn khác là sử dụng view-transition-name chung, nhưng chỉ áp dụng sau khi người dùng nhấp vào một bài đăng, nhưng trước khi gọi document.startViewTransition().

Thiết kế hiệu ứng chuyển cảnh

Chuyển đổi chế độ xem là một bộ công cụ mà bạn có thể dùng để hướng dẫn người dùng và cung cấp thêm thông tin gợi ý về thương hiệu hoặc bối cảnh. Bạn có thể sử dụng nhiều kỹ thuật để tìm ra các hiệu ứng chuyển đổi phù hợp với trang web của mình.

Tuỳ thuộc vào hiệu ứng mà bạn muốn, bạn cũng có thể cần điều chỉnh các phần tử hoặc ảnh động. Trong ví dụ trước, một số kiểu đã được điều chỉnh để có hiệu ứng chuyển đổi mượt mà.

Tiêu đề có quy tắc width: fit-content, đây là một kiểu hữu ích khi bạn chuyển đổi văn bản không xuống dòng (hoặc có cùng cách xuống dòng trong cả khung hiển thị cũ và mới. Nếu không, hiệu ứng chuyển đổi có thể diễn ra giữa các phần tử có chiều rộng khác nhau, khiến hiệu ứng chuyển đổi kém mượt mà.

Hình ảnh cũng có tỷ lệ khung hình khác nhau ở chế độ xem cũ và chế độ xem mới. Ví dụ này sửa đổi ảnh động và thuộc tính object-fit để quá trình chuyển đổi diễn ra mượt mà.

Tôn trọng prefers-reduced-motion

Một lý do phổ biến khiến người dùng yêu cầu giảm chuyển động là vì ảnh động toàn màn hình (chẳng hạn như ảnh động có thể đạt được bằng hiệu ứng chuyển đổi khung hiển thị) có thể gây khó chịu cho những người mắc chứng rối loạn tiền đình. Bạn có thể tắt ảnh động bằng cách sử dụng truy vấn nội dung nghe nhìn prefers-reduced-motion. Bạn cũng có thể chọn cung cấp các ảnh động thay thế tinh tế hơn nhưng vẫn truyền tải được cách các phần tử kết nối với nhau.

@media (prefers-reduced-motion) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
}

Kiểm tra mức độ hiểu biết của bạn

Tên của phần tử giả đại diện cho khung hiển thị trước khi document.startViewTransition() được gọi là gì?

::view-transition-previous
Sai.
::view-transition-prior
Sai.
::view-transition-old
Chính xác!
::view-transition-initial
Sai.

Ảnh động mặc định cho hiệu ứng chuyển đổi View là gì?

Làm mờ nội dung cũ khi nội dung mới xuất hiện
Chính xác!
Trượt từ trái sang phải
Sai.
Chuyển dần từ màu cũ sang màu trắng, rồi chuyển dần sang màu mới
Sai.
Gạt hình kiểu ngôi sao
Sai.

view-transition-name mặc định của một trang là gì?

document
Sai.
shadow-root
Sai.
root
Chính xác!
body
Sai.