尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Svelte transition 指令完全指南:原理、内置过渡、自定义函数与源码实现解析
Svelte transition 指令完全指南原理、内置过渡、自定义函数与源码实现解析【免费下载链接】svelteweb development for the rest of us项目地址: https://gitcode.com/GitHub_Trending/sv/svelteTransition过渡是 Svelte 中由元素因状态变化而进入或离开 DOM这一事件触发的动画机制。本文基于官方文档 14-transition.md系统讲解transition:指令的用法、svelte/transition内置过渡的参数细节、自定义过渡函数的规范、过渡事件以及可访问性处理并深入当前仓库的编译器与运行时源码剖析局部 vs 全局过渡、可逆双向过渡、css与tick的底层执行路径帮助你在掌握 API 的同时理解其实现原理。基本概念transition 何时触发transition由元素进入或离开 DOM触发而进出 DOM 通常由状态变化引起。两个关键特性当一个块如{#if ...}块正在离场transitioning out时块内所有元素——包括自身没有过渡的元素——都会保留在 DOM 中直到块内所有过渡全部完成。transition:指令表示一个双向bidirectional过渡即过渡进行到一半时可以平滑反向。最典型的应用示例script import { fade } from svelte/transition; let visible $state(false); /script button onclick{() visible !visible}toggle/button {#if visible} div transition:fadefades in and out/div {/if}{#if visible}的求值结果变化时div进出 DOMtransition:fade便同时覆盖了入场intro和离场outro两个方向。编译器如何生成过渡代码从源码结构看编译器在处理过渡指令时会将其编译为运行时内部函数$.transition的调用。见 TransitionDirective.js通过位标志编码修饰符global修饰符置TRANSITION_GLOBAL位in:置TRANSITION_IN位out:置TRANSITION_OUT位二者同时出现即transition:则方向为both参数以 thunk惰性求值的箭头函数形式传入因此过渡参数表达式可以在运行时反复求值调用语句被推入context.state.after_update源码注释说明这是为了确保它总是在bind:this之后执行从而保证过渡函数拿到的是正确的节点引用若参数表达式是异步的例如含await编译器会用$.run_after_blockers包裹该语句等阻塞表达式完成后再执行过渡初始化。局部local与全局global过渡过渡默认是局部的local只有当过渡所属的直接父块被创建或销毁时才播放而不会因为更外层的父块创建/销毁而播放。加上|global修饰符后任意祖先块的变化都会触发它。{#if x} {#if y} p transition:fadefades in and out only when y changes/p p transition:fade|globalfades in and out when x or y change/p {/if} {/if}运行时如何区分二者在 transitions.js 中transition()在创建过渡管理器后若是 intro 且处于应播放 intro的场景should_intro会向上查找最近的块级 effect跳过透明块snippet、else if块等标记为EFFECT_TRANSPARENT的 effect检查该块 effect 是否带有REACTION_RAN标志——即状态变化是否发生在这个块自身而不是它的祖先。局部过渡只有此时才真正创建 intro effect全局过渡则跳过上述判断直接播放。这正是局部过渡只在y变化时播放、|global过渡在x或y变化时都播放的底层依据。内置过渡svelte/transition 模块一系列内置过渡可从svelte/transition模块导入实现位于 transition/index.js类型定义见 public.d.ts。全部内置函数签名如下参数均可选括号内为源码中的默认值过渡函数动画内容特有参数fade(node, params)透明度从 0 到当前计算值delay0, duration400, easinglinearfly(node, params)x/y 位移 透明度x0, y0, opacity0, easingcubic_outslide(node, params)沿主轴展开/收起同时缩放高度/宽度、padding、margin、borderaxisyx \| yscale(node, params)缩放 透明度start0, opacity0, easingcubic_outblur(node, params)模糊滤镜 透明度amount5支持带单位的字符串,opacity0draw(node, params)SVG 路径描边动画要求节点有getTotalLength()speed或duration800/duration(len)函数crossfade(params)生成send/receive一对跨位置过渡见下文fallback(node, params, intro)所有内置过渡都遵循统一的TransitionConfig返回结构export interface TransitionConfig { delay?: number; duration?: number; easing?: EasingFunction; // (t: number) number css?: (t: number, u: number) string; tick?: (t: number, u: number) void; }几个实现细节值得注意fade会先读取getComputedStyle(node).opacity作为目标值因此元素本身有半透明样式时过渡是在当前透明度的 0 到 1之间进行而不是硬编码 0→1fly中位移量使用(1 - t) * value计算即in过渡t 从 0 到 1时从偏移量回到原点且会保留元素原有的transformslide对每一帧返回overflow: hidden;前缀并在运行时若检测到关键帧包含overflow: hidden会以行内样式补上——源码注释指出这是为了规避 Safari 18 之前的 bug见 transitions.js 的needs_overflow_hidden逻辑draw通过stroke-dasharray与stroke-dashoffset实现画线效果speed与duration二选一给speed时duration len / speed给函数形式的duration时以路径总长len求值crossfade返回[send, receive]一对过渡函数内部用两个Map按key配对发送方与接收方元素并基于getBoundingClientRect()计算位移、缩放与透明度插值若某节点没有对应的另一半列表项消失则回退到可选的fallback过渡。过渡参数过渡可以携带参数。文档特别说明双花括号{{...}}不是特殊语法就是表达式标签里的一个对象字面量。{#if visible} div transition:fade{{ duration: 2000 }}fades in and out over two seconds/div {/if}参数对象在运行时通过get_params?.()惰性求值后传给过渡函数见$.transition的get_options()。由于是 thunk参数可以引用响应式状态——例如下一节示例中prefersReducedMotion.current变化时参数会随之更新。可访问性prefers-reduced-motion过渡由Web Animations API驱动而不是 CSS 过渡/动画因此一条将transition-duration和animation-duration置零的全局media (prefers-reduced-motion: reduce)规则对 Svelte 过渡没有效果。正确做法是使用svelte/motion提供的prefersReducedMotion自 5.7.0 引入来调整或完全禁用过渡。其实现见 motion/index.js——它本质上是一个订阅(prefers-reduced-motion: reduce)媒体查询的MediaQuery响应式对象.current属性会在系统偏好变化时更新从而驱动响应式依赖script import { prefersReducedMotion } from svelte/motion; import { fly } from svelte/transition; let visible $state(false); /script {#if visible} p transition:fly{{ y: prefersReducedMotion.current ? 0 : 200 }} flies in, unless the user prefers reduced motion /p {/if}由于过渡参数是响应式表达式用户开关减少动态效果后参数会重新求值后续过渡立即按新参数播放。自定义过渡函数自定义过渡函数的完整签名transition (node: HTMLElement, params: any, options: { direction: in | out | both }) { delay?: number, duration?: number, easing?: (t: number) number, css?: (t: number, u: number) string, tick?: (t: number, u: number) void }其中options是第三个参数目前包含direction取值为in、out或both。在运行时源码中可以确认transition()根据TRANSITION_IN/TRANSITION_OUT标志计算directionin:out:同时存在时为both并作为第三个参数传给过渡函数见 TransitionDirective.js 生成代码与 transitions.js 的get_options()。关键语义若返回对象带css函数Svelte 会为其生成 Web Animations 的关键帧css收到的t是经过easing处理后的 0~1 值。in过渡t从 0 走到 1out过渡t从 1 走到 0——1永远是元素的自然状态相当于没施加任何过渡u恒等于1 - tcss/tick会在过渡开始前被反复调用不同的t、u用于预计算关键帧序列。使用 css 的示例缩放 弹性缓动!--- file: App.svelte --- script import { elasticOut } from svelte/easing; /** type {boolean} */ export let visible; /** * param {HTMLElement} node * param {{ delay?: number, duration?: number, easing?: (t: number) number }} params */ function whoosh(node, params) { const existingTransform getComputedStyle(node).transform.replace(none, ); return { delay: params.delay || 0, duration: params.duration || 400, easing: params.easing || elasticOut, css: (t, u) transform: ${existingTransform} scale(${t}) }; } /script {#if visible} div in:whooshwhooshes in/div {/if}NOTE能用css就用css不要用tick——Web Animations 可以脱离主线程运行避免在低性能设备上产生卡顿。使用 tick 的示例打字机效果自定义过渡函数还可以返回tick函数它在过渡进行中每帧被调用参数同样是t与u!--- file: App.svelte --- script export let visible false; /** * param {HTMLElement} node * param {{ speed?: number }} params */ function typewriter(node, { speed 1 }) { const valid node.childNodes.length 1 node.childNodes[0].nodeType Node.TEXT_NODE; if (!valid) { throw new Error(This transition only works on elements with a single text node child); } const text node.textContent; const duration text.length / (speed * 0.01); return { duration, tick: (t) { const i ~~(text.length * t); node.textContent text.slice(0, i); } }; } /script {#if visible} p in:typewriter{{ speed: 1 }}The quick brown fox jumps over the lazy dog/p {/if}延迟函数返回值多个过渡如何协同如果过渡函数返回的是函数而不是过渡配置对象该函数会在下一个 microtask 中被调用。这允许多个过渡相互协调从而实现 crossfade 这类延迟过渡——两个列表的元素需要等 DOM 更新完毕后互相看见对方才能计算位移。运行时源码印证了这一点animate()中检测到options是函数时会queue_micro_task延迟执行并返回一个同步的 facadeabort/deactivate/reset/t让调用方无需async/await也能正确中止或查询进度见 transitions.js。crossfade正是利用了这一机制。可逆双向过渡的实现transition:的中途平滑反转能力在源码中由counterpart对手方动画实现intro 与 outro 互相持有引用。当反向过渡开始时运行时会读取counterpart?.t()获取对手方当前进度t1以t1为起点、按剩余比例Math.abs(delta)缩放时长重新生成关键帧于是动画从当前画面无缝反方向进行而不是从头重放见 transitions.js 的animation.onfinish回调。同样地过渡进行中被重新求值的参数会沿用旧 optionscurrent_options ?? ...防止因duration等变化导致画面跳变。过渡事件带过渡的元素除了标准 DOM 事件外还会派发四个自定义事件introstart/introend入场开始 / 结束outrostart/outroend离场开始 / 结束源码中由dispatch_event()通过element.dispatchEvent(new CustomEvent(type))派发且包在without_reactive_context中避免事件回调内的状态写入被意外追踪见 transitions.js。{#if visible} p transition:fly{{ y: 200, duration: 2000 }} onintrostart{() (status intro started)} onoutrostart{() (status outro started)} onintroend{() (status intro ended)} onoutroend{() (status outro ended)} Flies in and out /p {/if}运行时执行路径小结将上文源码证据串起来一次过渡的完整执行路径是编译期TransitionDirectivevisitor 将transition:fade|global{{...}}编译为带标志位的$.transition(flags, element, fn, paramsThunk)调用并插入到after_update阶段初始化transition()解析direction创建{ is_global, in, out, stop }管理器挂到当前 effect 的nodes.t上对 intro按局部/全局规则决定是否创建播放 effect播放animate()先排队一个 microtask——源码注释解释这是为了让同一批次的嵌套过渡都先测量 DOM 再施加初始样式且仍在下一帧绘制之前完成随后创建一个fill: forwards的占位动画覆盖delay期防止元素在无样式的状态下被绘制关键帧delay 结束后按duration / (1000/60)向上取整的帧数逐帧调用css(t, u)生成关键帧数组再调用element.animate(keyframes, { duration, fill: forwards })每帧 tick若配置含tick通过loop()在动画running期间按当前currentTime映射出t并回调事件与收尾onfinish触发introend/outroend清理占位动画与临时样式abort()则取消动画并置空effect/onfinish源码注释指明这是为防止 Chromium 内存泄漏及cancel()后误触发onfinish。相关资源内置过渡实现transition/index.js类型定义transition/public.d.ts客户端运行时核心transitions.js编译器指令处理TransitionDirective.jsprefersReducedMotion实现motion/index.js官方文档原文14-transition.md测试用例runes 运行时tests/runtime-runes/samples其中包含dynamic-transition、async-transition-blockers、transition-component等与过渡相关的样本目录可用于验证不同使用场景下的行为【免费下载链接】svelteweb development for the rest of us项目地址: https://gitcode.com/GitHub_Trending/sv/svelte创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

WPF自定义TimePicker控件:仿ElementUI交互与MVVM双向绑定实践

WPF自定义TimePicker控件:仿ElementUI交互与MVVM双向绑定实践

简介:仿照ElementUI TimePicker交互风格,用WPF与C#实现桌面端时间选择器组件,面向熟悉MVVM模式、希望提升WPF自定义控件能力的.NET开发者。资源基于Visual Studio工程WpfApp1,素材包含完整实现:主窗口XAML布局、ViewMo…

📅 2026/10/11 21:54:29
ASP.NET Core 6 Web API对接海康HLS流实战指南

ASP.NET Core 6 Web API对接海康HLS流实战指南

简介:一份面向.NET开发者的ASP.NET Core 6 Web API入门示例,演示如何结合Entity Framework Core实现RESTful接口。资源包含完整的项目源码,基于.NET 6.0构建,覆盖从服务配置、数据库上下文、迁移、控制器到实体模型的完整开发链路…

📅 2026/10/27 6:56:00
串口转网络原理与实战:TCP/UDP转换、配置调试全攻略

串口转网络原理与实战:TCP/UDP转换、配置调试全攻略

简介:面向工业现场、嵌入式设备及物联网场景中的通信互通需求,这份资源提供了“串口转网络”和“网络转串口”双向转换工具,支持TCP/UDP两种主流传输方式,适合需将RS-232/RS-485等串口设备接入以太网或互联网,实现远程…

📅 2026/10/13 3:11:35
MORE NEWS

更多资讯

📰

弱电没有电工证也别慌 良心建议帮你理清实操考试内容

弱电没有电工证也别慌 良心建议帮你理清实操考试内容 你正愁找不到电工证,想着先上岗再考证?别傻了,现在弱电行业 没有电工证根本进不了门 ,连面试都过不了。别再听那些“先干着干着就懂了”的鬼话,现在行业规范越抓越紧,…

📰

电工作业证电工上岗证官方回应:证书过期了不知道怎么复审延期

电工作业证电工上岗证官方回应:证书过期了不知道怎么复审延期 证书过期了不知道怎么复审延期?这事儿不少电工朋友都遇到过。特别是像我们南阳的水利工程从业者,经常在工地上操作电器设备,一旦证书没及时复审,轻则影响工作,重则可能面临违规处罚。郑州市…

📰

合川低压电工证哪里考多少钱才不被中介坑

合川低压电工证哪里考多少钱才不被中介坑 你是不是也和我一样,听说要考低压电工证,但不知道 合川低压电工证哪里考 ,怕被中介忽悠,还担心 多少钱 一个证?别急,今天就来聊聊怎么在合川这地方,安全、靠谱地拿到低压电工证。…

📰

上海闸北附近电工证官方回应:证书过期了怎么复审延期

上海闸北附近电工证官方回应:证书过期了怎么复审延期 证书过期了不知道怎么复审延期?别急,今天咱们就来聊聊上海闸北附近电工证的那些事儿,尤其是复审和延期这些大家最关心的问题。官方回应已经明确,特种作业操作证的复审流程并不复杂,但一定要按照规范…

📰

上海长宁区电工证真实经历:证书过期了不知道怎么复审延期怎么办?

上海长宁区电工证真实经历:证书过期了不知道怎么复审延期怎么办? 证书过期了不知道怎么复审延期?这事儿我真遇到过,当时整个人都懵了。作为一名在许昌市政公用工程单位干活的电工,我深知特种作业证不是摆设,它关系到我们每个人的生命安全,也关系到我们…

📰

郯城县考点电工证通过率揭秘:工地太忙根本没时间复习考试怎么办?

郯城县考点电工证通过率揭秘:工地太忙根本没时间复习考试怎么办? 工地太忙根本没时间复习考试,这几乎是所有在一线施工的电工朋友都遇到的难题。特别是在郯城县考点报考电工证的工友,既想趁政策利好抓住机会,又怕因为时间不够而挂科。很多人问:“…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬