diff --git a/src/content/docs/zh-cn/guides/view-transitions.mdx b/src/content/docs/zh-cn/guides/view-transitions.mdx index b0dbde03ce8c4..cdd94deb8f136 100644 --- a/src/content/docs/zh-cn/guides/view-transitions.mdx +++ b/src/content/docs/zh-cn/guides/view-transitions.mdx @@ -3,6 +3,7 @@ title: 视图过渡动画 description: 在 Astro 中通过视图过渡动画实现页面之间的无缝导航。 i18nReady: true --- +import ReadMore from '~/components/ReadMore.astro' import Since from '~/components/Since.astro' import { Steps } from '@astrojs/starlight/components' @@ -317,7 +318,7 @@ const customTransition = { ### 触发导航 -你还可以使用 `navigate` 方法在通常不被 `` 路由器监听的事件里触发客户端导航。该函数来自于 `astro:transitions/client` 模块,可以在任何客户端脚本和通过[客户端指令](/zh-cn/reference/directives-reference/#客户端指令)激活了的客户端组件中使用。 +你还可以使用 [`navigate()`](/zh-cn/reference/modules/astro-transitions/#navigate) 方法在通常不被 `` 路由器监听的事件里触发客户端导航。该函数来自于 `astro:transitions/client` 模块,可以在任何客户端脚本和通过[客户端指令](/zh-cn/reference/directives-reference/#客户端指令)激活了的客户端组件中使用。 下面的示例展示了一个当访客选择菜单中的选项时导航到另一个页面的 Astro 组件: @@ -387,27 +388,17 @@ import { ClientRouter } from "astro:transitions"; ``` -`navigate` 方法接受以下参数: - -- `href`(必需项)- 要导航到的新页面。 -- `options` - 一个可选的对象,具有以下属性: - - `history`: `"push"` | `"replace"` | `"auto"` - - `"push"`: 路由器将使用 `history.pushState` 在浏览器历史中创建一个新条目。 - - `"replace"`: 路由器将使用 `history.replaceState` 更新 URL,而不向导航添加新条目。 - - `"auto"`(默认): 路由器将尝试使用 `history.pushState`,但如果无法转换到指定的 URL,则当前 URL 将保持不变,浏览器历史不会发生变化。 - - `formData`: 一个 `POST` 请求的 [`FormData`](https://developer.mozilla.org/zh-CN/docs/Web/API/FormData) 对象。 - 要想通过浏览器的历史记录进行后退和前进导航,你可以将 `navigate()` 与浏览器内置的 `history.back()`、`history.forward()` 和 `history.go()` 等函数结合使用。如果 `navigate()` 在服务器渲染时被调用,它不会有任何效果。 +查看 `astro:transitions` 参考获得关于 [`navigate()` 选项](/zh-cn/reference/modules/astro-transitions/#navigate) 的更多信息。 + ### 替换浏览器历史条目 通常情况下,你每次导航时都会在浏览器的历史记录中写入一个新条目。这样可以使用浏览器的 `back` 和 `forward` 按钮在页面之间导航。 `` 路由器器允许你通过向任何单独的 `` 标签添加 `data-astro-history` 属性来覆盖历史记录条目。 -`data-astro-history` 属性可以设置为与 [`navigate()` 函数的 `history` 选项](#触发导航)相同的三个值: - -`data-astro-history`: `"push"` | `"replace"` | `"auto"` +`data-astro-history` 属性可以设置为与 [`navigate()` 函数的 `history` 选项](/zh-cn/reference/modules/astro-transitions/#history-选项)相同的三个值: - `'push'`:路由器将使用 `history.pushState` 在浏览器历史记录中创建一个新条目。 - `'replace'`:路由器将使用 `history.replaceState` 更新 URL 而不添加新的导航条目。 @@ -443,6 +434,30 @@ import { ClientRouter } from "astro:transitions";
``` +### 使用用户输入进行导航 + +`navigate()` API 不会对传递给它的 URL 执行无害化处理。如果你使用用户输入来确定导航的 URL,你应该在将输入传递给 `navigate()` 之前对其进行验证。 + +例如,如果在使用前没有对传入值进行无害化处理,`?redirect` query 参数可能会被用于导航到外部网站(`?redirect=http://example.com`)或执行任意代码(`?redirect=javascript:alert('Evil code')`)。 + +一种安全的实现方式是确保只能重定向到一组已知路径: + +```astro title="src/pages/index.astro" + +``` + +所需的具体净化措施取决于你的网站以及你想要允许的内容范围。 + +如果将用户输入与 `navigate()` API 一起使用,请考虑启用 Astro 的 [实验性内容安全策略功能](/zh-cn/reference/experimental-flags/csp/),来帮助防范跨站脚本攻击(XSS)的风险。 + ## 回退控制 `` 路由器在支持视图过渡动画的浏览器(如 Chromium 浏览器)中表现最佳,但也包含了对其他浏览器的默认回退支持。即使当浏览器不支持视图过渡动画 API 时,Astro 的客户端路由仍然可以使用其中一个回退选项提供来浏览器导航。 @@ -602,7 +617,7 @@ Astro 的视图过渡动画 API 生命周期事件顺序如下: - 更改加载内容,例如从模板中加载而不是从外部 URL 加载。 - 在加载时更改 `direction`(通常为 `forward` 或 `backward`)以进行自定义动画。 -以下示例展示了如何在内容加载前使用 `astro:before-preparation` 事件加载一个加载指示器,并在加载完成后立即停止它。请注意,以这种方式使用 `loader` 回调允许异步执行代码。 +以下示例展示了如何在内容加载前使用 `astro:before-preparation` 事件加载一个加载指示器,并在加载完成后立即停止它。请注意,以这种方式使用 [`loader`](/zh-cn/reference/modules/astro-transitions/#loader) 回调允许异步执行代码。 ```astro +import { + getFallback, + navigate, + supportsViewTransitions, + swapFunctions, + transitionEnabledOnThisPage, + /* 以下将在v6版本中弃用: */ + isTransitionBeforePreparationEvent, + isTransitionBeforeSwapEvent, + TRANSITION_AFTER_PREPARATION, + TRANSITION_AFTER_SWAP, + TRANSITION_BEFORE_PREPARATION, + TRANSITION_BEFORE_SWAP, + TRANSITION_PAGE_LOAD, +} from 'astro:transitions/client'; ``` ### `navigate()` @@ -115,10 +137,12 @@ import { slide } from 'astro:transitions';

-一个使用视图过渡 API 导航到给定 `href` 的函数。 +使用视图过渡 API 导航到给定 `href`。 此函数签名基于 [浏览器 Navigation API 中的 `navigate` 函数](https://developer.mozilla.org/en-US/docs/Web/API/Navigation/navigate)。虽然基于 Navigation API,但此函数是在 [History API](https://developer.mozilla.org/zh-CN/docs/Web/API/History_API) 之上实现的,以允许在不重新加载页面的情况下进行导航。 +`navigate()` 函数不会对 `href` 参数进行无害化处理。若使用用户输入来确定导航目标 URL,[请对输入进行无害化处理](/zh-cn/guides/view-transitions/#使用用户输入进行导航)。 + #### `history` 选项

@@ -170,7 +194,7 @@ import { slide } from 'astro:transitions';

-与导航相关的 `NavitationHistoryEntry` 对象中关联的任意数据。此数据可以通过 [`history.getState` 函数](https://developer.mozilla.org/en-US/docs/Web/API/NavigationHistoryEntry/getState) 从 History API 中检索。 +与导航相关的 `NavigationHistoryEntry` 对象中关联的任意数据。此数据可以通过 [`history.getState` 函数](https://developer.mozilla.org/en-US/docs/Web/API/NavigationHistoryEntry/getState) 从 History API 中检索。 此选项模仿了浏览器 Navigation API 中的 [`state` 选项](https://developer.mozilla.org/en-US/docs/Web/API/Navigation/navigate#state)。 @@ -183,8 +207,8 @@ import { slide } from 'astro:transitions';

此导航的触发元素,如果有的话。此元素将在以下事件中可用: -- `astro:before-preparation` -- `astro:before-swap` +- [`astro:before-preparation`](#astrobefore-preparation-事件) +- [`astro:before-swap`](#astrobefore-swap-事件) ### `supportsViewTransitions` @@ -196,11 +220,11 @@ import { slide } from 'astro:transitions'; 当前浏览器是否支持并启用视图过渡。 -### `transitionEnabledOnThisPage` +### `transitionEnabledOnThisPage()`

-**类型:**`boolean`
+**类型:**`() => boolean`

@@ -210,18 +234,20 @@ import { slide } from 'astro:transitions';

-**类型:**`() => 'none' | 'animate' | 'swap'`
+**类型:** () =>
Fallback
+**默认值:** `animate`

-返回在浏览器不支持视图过渡时使用的回退策略。 +返回在浏览器不支持视图过渡时使用的回退策略(默认 `animate`)。 -有关如何选择和配置回退行为的详细信息,请参阅 [回退控制](/zh-cn/guides/view-transitions/#回退控制) 指南。 +有关如何选择和配置回退行为的详细信息,请参阅 [回退控制](/zh-cn/guides/view-transitions/#回退控制) 指南。 ### `swapFunctions`

+**类型:** `object`

@@ -277,34 +303,364 @@ import { slide } from 'astro:transitions'; 用新 document 的 body 替换旧的 body。然后,遍历旧 body 中应持久化的每个元素,并在新 body 中找到匹配的元素,将旧元素交换回原位。 +### 已弃用的导入项 + +以下导入项计划在 v6 版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 + +

`isTransitionBeforePreparationEvent()`

+ +

+ +**类型:** `(value: any) => boolean`
+ +

+ +:::caution[计划弃用] +此函数计划在 v6 版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +判断给定值是否匹配 [`TransitionBeforePreparationEvent`](#transitionbeforepreparationevent) 类型。当需要在事件监听器中缩小事件类型范围时,此功能非常实用。 + +```astro title="src/pages/index.astro" "isTransitionBeforePreparationEvent" +--- +--- + + +``` + +

`isTransitionBeforeSwapEvent()`

+ +

+ +**类型:** `(value: any) => boolean`
+ +

+ +:::caution[计划弃用] +此函数计划在 v6 版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +判断给定值是否匹配 [`TransitionBeforeSwapEvent`](#transitionbeforeswapevent) 类型。当需要在事件监听器中缩小事件类型范围时,此功能非常实用。 + +```astro title="src/pages/index.astro" "isTransitionBeforeSwapEvent" +--- +--- + + +``` + +

`TRANSITION_BEFORE_PREPARATION`

+ +

+ +**类型:** `'astro:before-preparation'`
+ +

+ +:::caution[计划弃用] +此常量计划在 v6 版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +一个常量,用于在定义事件时避免直接以明文形式书写 `astro:before-preparation` 事件名称。 + +```astro title="src/pages/index.astro" "TRANSITION_BEFORE_PREPARATION" +--- +--- + + +``` + +

`TRANSITION_AFTER_PREPARATION`

+ +

+ +**类型:** `'astro:after-preparation'`
+ +

+ +:::caution[计划弃用] +此常量计划在 v6版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +一个常量,用于在定义事件时避免直接以明文形式书写 `astro:after-preparation` 事件名称。 + + +```astro title="src/pages/index.astro" "TRANSITION_AFTER_PREPARATION" +--- +--- + + +``` + +

`TRANSITION_BEFORE_SWAP`

+ +

+ +**类型:** `'astro:before-swap'`
+ +

+ +:::caution[计划弃用] +此常量计划在 v6版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +一个常量,用于在定义事件时避免直接以明文形式书写 `astro:before-swap` 事件名称。 + +```astro title="src/pages/index.astro" "TRANSITION_BEFORE_SWAP" +--- +--- + + +``` + +

`TRANSITION_AFTER_SWAP`

+ +

+ +**类型:** `'astro:after-swap'`
+ +

+ +:::caution[计划弃用] +此常量计划在 v6版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +一个常量,用于在定义事件时避免直接以明文形式书写 `astro:after-swap` 事件名称。 + +```astro title="src/pages/index.astro" "TRANSITION_AFTER_SWAP" +--- +--- + + +``` + +

`TRANSITION_PAGE_LOAD`

+ +

+ +**类型:** `'astro:page-load'`
+ +

+ +:::caution[计划弃用] +此常量计划在 v6版本中弃用。你仍可在项目中使用它们,但建议现在就更新代码。 +::: + +一个常量,用于在定义事件时避免直接以明文形式书写 `astro:page-load` 事件名称。 + +```astro title="src/pages/index.astro" "TRANSITION_PAGE_LOAD" +--- +--- + + +``` + +## `astro:transitions/client` 类型 + +```ts +import type { + Direction, + Fallback, + NavigationTypeString, + Options, + TransitionBeforePreparationEvent, + TransitionBeforeSwapEvent, +} from 'astro:transitions/client'; +``` + +### `Direction` + +

+ +**类型:** `'forward' | 'back'`
+ +

+ +动画方向的联合类型: +- `forward`:导航到历史记录中的下一页或新页面。 +- `back`:导航到历史记录中的上一页。 + +### `Fallback` + +

+ +**类型:** `'none' | 'animate' | 'swap'`
+ +

+ +在不支持视图过渡的浏览器中使用的一套回退策略: +- `animate`:Astro 会在更新页面内容之前使用自定义属性来模拟视图过渡。 +- `swap`:Astro 将不会尝试对页面进行动画处理。相反,旧页面将被新页面立即替换。 +- `none`:Astro 不会执行任何动画页面过渡。相反,在不支持动画页面过渡的浏览器中,你将获得完整的页面导航。 + +学习如何使用 `ClientRouter` [控制回退策略](/zh-cn/guides/view-transitions/#回退控制)。 + +### `NavigationTypeString` + +

+ +**类型:** `'push' | 'replace' | 'traverse'`
+ +

+ +受支持的历史导航事件的联合类型。 + +### `TransitionBeforePreparationEvent` + +

+ +**类型:** `Event`
+ +

+ +表示一个 [`astro:before-preparation` 事件](#astrobefore-preparation-事件)。这对于为监听器接收到的事件指定类型很有用: + +```astro title="src/pages/index.astro" "TransitionBeforePreparationEvent" +--- +--- + + +``` + +### `TransitionBeforeSwapEvent` + +

+ +**类型:** `Event`
+ +

+ +表示一个 [`astro:before-swap` 事件](#astrobefore-swap-事件)。这对于为监听器接收到的事件指定类型很有用: + +```astro title="src/pages/index.astro" "TransitionBeforeSwapEvent" +--- +--- + + +``` + ## 生命周期事件 ### `astro:before-preparation` 事件 +

+ +**类型:** [`TransitionBeforePreparationEvent`](#transitionbeforepreparationevent)
+ +

+ 使用视图过渡路由开始导航时触发的事件。此事件发生在任何请求之前,并且不会更改任何浏览器状态。 此事件具有以下属性: - [`info`](#info) - [`sourceElement`](#sourceelement) - [`navigationType`](#navigationtype) -- [`direction`](#direction) +- [`direction`](#direction-1) - [`from`](#from) - [`to`](#to) - [`formData`](#formdata) - [`loader()`](#loader) -有关如何使用此事件的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#astrobefore-preparation)。 +有关如何使用此事件的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#astrobefore-preparation)。 ### `astro:after-preparation` 事件 +

+ +**类型:** `Event`
+ +

+ 使用视图过渡路由加载导航中的下一个页面后触发的事件。 此事件没有属性。 -有关如何使用此事件的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#astroafter-preparation)。 +有关如何使用此事件的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#astroafter-preparation)。 ### `astro:before-swap` 事件 +

+ +**类型:** [`TransitionBeforeSwapEvent`](#transitionbeforeswapevent)
+ +

+ 在视图过渡中导航的下一个页面解析、准备并链接到 document 后,但在任何内容在 document 之间交换之前触发的事件。 此事件不能取消。调用 `preventDefault()` 是无效的。 @@ -313,22 +669,32 @@ import { slide } from 'astro:transitions'; - [`info`](#info) - [`sourceElement`](#sourceelement) - [`navigationType`](#navigationtype) -- [`direction`](#direction) +- [`direction`](#direction-1) - [`from`](#from) - [`to`](#to) - [`viewTransition`](#viewtransition) - [`swap`](#swap) -有关如何使用此事件的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#astrobefore-swap)。 +有关如何使用此事件的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#astrobefore-swap)。 ### `astro:after-swap` 事件 +

+ +**类型:** `Event` +

+ 在视图过渡中导航的下一个页面内容交换后,但在视图过渡结束之前触发的事件。 在触发此事件时,历史记录条目和滚动位置已经更新。 ### `astro:page-load` 事件 +

+ +**类型:** `Event` +

+ 在页面完成加载后触发的事件,无论是通过视图过渡导航还是浏览器原生导航。 当视图过渡在页面上启用时,通常在 `DOMContentLoaded` 上执行的代码应更改为在此事件上执行。 @@ -337,11 +703,13 @@ import { slide } from 'astro:transitions';

+以下属性在 [`astro:before-preparation`](#astrobefore-preparation-事件) 和 [`astro:before-swap`](#astrobefore-swap-事件) 事件中是通用的,但有些属性仅在其中一个事件中可用。 + #### `info`

-**类型:**`URL` +**类型:**`any`

在导航期间定义的任意数据。 @@ -372,26 +740,24 @@ import { slide } from 'astro:transitions';

-**类型:**`'push' | 'replace' | 'traverse'` +**类型:** [`NavigationTypeString`](#navigationtypestring)

正在发生的导航类型。 - `push`: 正在为新页面创建一个新的 `NavigationHistoryEntry`。 - `replace`: 当前的 `NavigationHistoryEntry` 正在被新页面的条目替换。 -- `traverse`: 没有创建 `NavigationHistoryEntry`。历史记录中的位置正在改变。 - 遍历的方向由 [`direction` 属性](#direction) 给出 +- `traverse`: 没有创建 `NavigationHistoryEntry`。历史记录中的位置正在改变。遍历的方向由 [`direction` 属性](#direction-1) 给出 #### `direction`

-**类型:**`Direction` +**类型:**`string`

过渡的方向。 -- `forward`: 在历史记录中导航到下一个页面或新页面。 -- `back`: 在历史记录中导航到前一个页面。 -- 其他监听器可能设置的任何其他内容。 +* 在 [`astro:before-preparation` 事件](#astrobefore-preparation-事件) 中,可用于定义自定义方向。该属性可写,接受任意字符串。 +* 在 [`astro:before-swap` 事件](#astrobefore-swap-事件) 中,可用于检索过渡方向。该属性为只读,其值可以是预定义的 [`Direction`](#direction),或任何由 `astro:before-preparation` 事件监听器设置的字符串。 #### `from` @@ -415,12 +781,11 @@ import { slide } from 'astro:transitions';

-**类型:**`FormData | undefined` +**类型:**`FormData | undefined`
+**可用于:** [`astro:before-preparation` 事件](#astrobefore-preparation-事件)

-一个用于 `POST` 请求的 `FormData` 对象。 - -当此属性设置时,将使用给定的表单数据对象作为内容发送 `POST` 请求到 [`to` URL](#to),而不是正常的 `GET` 请求。 +设置后,将向 [`to `URL] 发送一个 `POST` 请求,并以给定的 `FormData` 对象作为内容,而不是常规的 `GET` 请求。 当提交一个带有视图过渡的 HTML 表单时,此字段会自动设置为表单中的数据。当使用 [`navigate()` 函数](#navigate) 时,此值与给定的选项相同。 @@ -428,7 +793,8 @@ import { slide } from 'astro:transitions';

-**类型:**`() => Promise` +**类型:**`() => Promise`
+**可用于:** [`astro:before-preparation` 事件](#astrobefore-preparation-事件)

在导航过程中下个阶段的实现(加载下一个页面)。此实现可以覆盖以添加额外的行为。 @@ -437,7 +803,8 @@ import { slide } from 'astro:transitions';

-**类型:**[`ViewTransition`](https://developer.mozilla.org/zh-CN/docs/Web/API/ViewTransition) +**类型:**[`ViewTransition`](https://developer.mozilla.org/zh-CN/docs/Web/API/ViewTransition)
+**可用于:** [`astro:before-swap` 事件](#astrobefore-swap-事件)

在导航过程中使用的视图过渡对象。在浏览器不支持 [视图过渡 API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API) 的情况下,这是一个对象,实现了相同的 API 以方便使用,但没有 DOM 集成。 @@ -446,17 +813,16 @@ import { slide } from 'astro:transitions';

-**类型:**`() => void` +**类型:**`() => void`
+**可用于:** [`astro:before-swap` 事件](#astrobefore-swap-事件)

-document 交换逻辑的实现。 - -有关如何构建自定义交换函数的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#构建自定义交换函数). - -默认情况下,此实现将按顺序调用以下函数: +调用默认的文档替换逻辑。默认情况下,此实现将按以下顺序调用这些函数: 1. [`deselectScripts()`](#deselectscripts) 2. [`swapRootAttributes()`](#swaprootattributes) 3. [`swapHeadElements()`](#swapheadelements) 4. [`saveFocus()`](#savefocus) 5. [`swapBodyElement()`](#swapbodyelement) + +有关如何构建自定义交换函数的详细信息,请参阅 [视图过渡指南](/zh-cn/guides/view-transitions/#构建自定义交换函数)。