- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
交替文本动画是一种在网页中循环展示不同单词或短语的动态效果,常被用于呈现独特卖点或功能列表,为页面增添趣味性。本文基于 30-seconds-of-code 仓库中的 alternating-text 代码片段,完整讲解其实现原理:用 CSS@keyframes定义文本消失动画,再用 JavaScript 监听animationiteration事件在每次动画迭代结束后切换内容。读完本文,你将掌握这套零依赖的轮播式文字动画方案,并了解其可访问性短板与对应的优化思路。
一、核心原理:CSS 负责“消失”,JavaScript 负责“换词”
整个方案由两个层面协作完成:
- CSS 层:为目标元素挂上一个无限循环的动画,动画在每一轮迭代的末尾将文本隐藏(
display: none),制造出“文字闪没”的视觉缺口。 - JavaScript 层:预先定义一个待轮播的文本数组,用数组第一个词初始化元素内容,并通过
EventTarget.addEventListener()监听'animationiteration'事件——该事件恰好会在每次动画完成一轮迭代时触发。于是每次动画“闪没”之后,元素内容被更新为数组中的下一个词,从而形成连贯的交替轮播。
这种“动画事件驱动数据更新”的模式避免了定时器的使用,让文本切换节奏与 CSS 动画天然同步,是 30-seconds-of-code 中 CSS Animations 集合 所收录的典型动画交互技巧之一。
二、CSS 部分:定义交替文本动画
原文档给出的 CSS 定义如下,直接作用于承载轮播文本的元素:
.alternating { animation-name: alternating-text; animation-duration: 3s; animation-iteration-count: infinite; animation-timing-function: ease; } @keyframes alternating-text { 90% { display: none; } }各配置项的作用与可调范围:
| 属性 | 取值 | 作用 |
|---|---|---|
animation-name | alternating-text | 指定要应用的@keyframes动画名称,须与下方关键帧定义同名 |
animation-duration | 3s | 单次动画迭代的时长,直接决定每个词停留的时间,可依文案长度调整为1s、5s等 |
animation-iteration-count | infinite | 动画无限循环,是轮播效果成立的前提;若只想播放有限次数可改为数字 |
animation-timing-function | ease | 缓动函数,本示例动画无位移动画,此处影响不明显,可保留默认值 |
关键帧部分值得深入理解:@keyframes alternating-text只在90%时间点声明了display: none。这意味着动画前 90% 的时间元素保持显示,最后 10% 的时间被隐藏。由于动画无限循环,元素会在每个周期的末尾短暂消失——正是这个瞬间,JavaScript 利用animationiteration事件完成换词,让用户看到“上一个词消失、下一个词出现”的效果。
从 CSS 规范角度,
display属于不可动画属性,它无法像opacity或transform那样产生平滑过渡,只会瞬间切换。但在本场景中我们恰恰需要这种“瞬断”来隐藏旧词,因此用 90% 单一断点即可达成目的。
如果想做出更柔和的“淡出换词”效果,可以类比仓库中其他动画片段的写法,改用opacity配合过渡:例如在 zoomin-zoomout-animation 片段 中使用scale与transform实现缩放动画,在 loaders 片段 中则用opacity从1过渡到0实现脉冲加载环的消散效果。将这里 90% 处的display: none替换为opacity: 0,即可获得淡入淡出的交替体验。
三、JavaScript 部分:驱动内容循环切换
原文档给出的 JavaScript 实现如下:
const texts = ['Java', 'Python', 'C', 'C++', 'C#', 'Javascript']; const element = document.querySelector('.alternating'); let i = 0; const listener = e => { i = i < texts.length - 1 ? i + 1 : 0; element.innerHTML = texts[i]; }; element.innerHTML = texts[0]; element.addEventListener('animationiteration', listener, false);逐行拆解其工作机制:
- 文本数组:
texts定义要轮播的词或短语列表,可自由扩充为任意字符串集合(例如产品特性、促销短语、技术关键词)。 - 元素选择:
document.querySelector('.alternating')选取挂载了 CSS 动画的 DOM 元素。 - 索引游标:
i记录当前展示词在数组中的下标。listener回调中通过i < texts.length - 1 ? i + 1 : 0实现“到达末尾后回绕到 0”的循环逻辑,保证无限轮播。 - 初始化内容:
element.innerHTML = texts[0]在监听器注册之前先把第一个词写入元素,避免页面加载时出现空元素。 - 注册事件:
element.addEventListener('animationiteration', listener, false)监听动画迭代完成事件。第三个参数false表示在冒泡阶段捕获该事件;animationiteration事件会在由 CSS 动画驱动的迭代结束时触发,这里正是它与animation-iteration-count: infinite的配合点。
注意listener的回调形参e虽未在函数体内使用,但保留它是为了保持签名完整、便于后续扩展(例如通过e.animationName区分多个同时运行的动画——在同一个元素上叠加多个动画时,可用该属性判断到底哪个动画完成了迭代,再决定是否换词)。
四、完整可运行的整合示例
将 HTML、CSS、JavaScript 三者组合,即可得到一套开箱即用的交替文本轮播组件:
<div class="alternating"></div>.alternating { animation-name: alternating-text; animation-duration: 3s; animation-iteration-count: infinite; animation-timing-function: ease; } @keyframes alternating-text { 90% { display: none; } }const texts = ['Java', 'Python', 'C', 'C++', 'C#', 'Javascript']; const element = document.querySelector('.alternating'); let i = 0; const listener = e => { i = i < texts.length - 1 ? i + 1 : 0; element.innerHTML = texts[i]; }; element.innerHTML = texts[0]; element.addEventListener('animationiteration', listener, false);使用提示:
- 可为
.alternating补充font-size、color等样式,使其适配页面的视觉体系; - 若轮播词长度差异较大,可设置固定
min-width或text-align: center,避免每次换词时页面布局跳动; - 词数较多时可适当缩短
animation-duration,词数少(如 2~3 个)时则相应延长,让每个词都有充足的阅读时间。
五、性能与调优要点
- 保持动画轻量:本方案的动画只切换
display,不涉及transform、opacity的持续计算,主线程负担极小。如需扩展为淡入淡出效果,建议沿用仓库其他片段中对transform的优化思路(如 loaders 片段 中提示使用translate3d()单轴平移以获得更好的合成性能),避免对width、height这类触发重排的属性做动画。 - 事件驱动的节奏一致性:因为换词动作绑定在
animationiteration事件上,只要动画时长稳定,换词节奏就与视觉消失瞬间严格对齐,不会出现“词还没消失就已换掉”或“消失很久才换词”的错位。
六、可访问性警示(原文档明确提示)
原文档对这套实现给出了明确的警告,务必重视:
[!CAUTION] 该实现对屏幕阅读器不可访问(not accessible to screen readers)。因为轮播中的旧词会被
display: none隐藏、新词通过innerHTML动态替换,屏幕阅读器无法稳定地读出正在展示的内容。
要提升可访问性,可以采取以下措施(依原文档建议方向):
- ARIA 属性:为轮播容器设置
role="status"或aria-live="polite",让辅助技术感知内容变化并朗读最新文本; - 语义化降级:将轮播文本的完整列表以静态、可读的形式保留在页面中(例如紧随其后的
<ul>列表),保证关闭 JavaScript 或使用辅助技术时信息不丢失; - 替代方案:必要时放弃 JS 轮播,改用 CSS 变量驱动的纯静态逐词展示,或参考仓库中 typewriter-effect 片段 这类同样轻量但信息呈现更线性的动画方案,结合
aria-label为容器提供等价文本。
七、延伸:同主题动画片段的横向参考
交替文本动画属于 30-seconds-of-code 中 CSS Animations 集合 的成员(该集合由tagMatcher: animation聚合所有动画主题片段)。若你正在搭建一组品牌化的动态文字效果,可以与本仓库内其他动画片段配合使用:
- typewriter-effect 片段:基于 CSS 变量与
steps()逐字显现的打字机效果,同样只用少量 JavaScript 设置文本,风格更偏叙事与悬念; - loaders 片段:弹跳小球、脉冲涟漪、甜甜圈旋转三种加载指示器,适合与轮播文案搭配用于异步内容占位;
- zoomin-zoomout-animation 片段:单元素的
scale缩放循环动画,可用于强调当前展示词。
八、小结
交替文本动画的完整实现可概括为三步:定义无限循环的 CSS 动画并在末尾隐藏元素 → 用数组首个元素初始化内容 → 监听animationiteration事件在每次迭代后切换到下一词。这套方案代码量小、无第三方依赖,非常适合用于卖点轮播、特性陈列等场景;同时必须铭记其屏幕阅读器不可访问的缺陷,在投入生产环境前应补充 ARIA 或静态文本降级方案。原始代码片段收录于 content/snippets/css/s/alternating-text.md,你可随时回到仓库查看最新版本。
- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
相关推荐
30 Seconds of Code:用 CSS 缓动变量(Easing Variables)打造高级动画节奏
30 Seconds of Code:用 CSS 缓动变量(Easing Variables)打造高级动画节奏 导读 本文源自 30 seconds of co
教程文档30 Seconds of Code 实战:用纯 CSS 打造环形进度条(SVG + CSS 变量 + @property)
30 Seconds of Code 实战:用纯 CSS 打造环形进度条(SVG + CSS 变量 + @property) 环形进度条(circular pr
教程文档CSS 渐变文字效果实战:用 `background-clip` 与 `-webkit-text-fill-color` 打造渐变文字(30 seconds of code)
CSS 渐变文字效果实战:用 background clip 与 webkit text fill color 打造渐变文字(30 seconds of cod
教程文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考