使用 HTML、CSS 和 JavaScript 创建动态打字机效果

使用 HTML、CSS 和 JavaScript 创建动态打字机效果

本文详细介绍了如何利用 HTML 结构、CSS 动画和 JavaScript 逻辑实现一个动态的打字机文本效果。教程涵盖了 HTML 元素的设置、CSS 光标闪烁动画的实现,以及 JavaScript 中文本数组管理、字符逐一输出和动画循环的关键函数,确保文本内容能被精确地逐字显示并循环播放。

引言

网页设计中,动态效果能够显著提升用户体验和页面的吸引力。打字机效果(typewriter effect)便是其中一种常见的动画,它模拟了文本逐字输入的过程,常用于突出关键信息、制作引导语或增加页面的趣味性。本教程将指导您如何结合 htmlcssjavascript,从零开始构建一个可自定义的打字机文本动画。

1. HTML 结构:定义文本容器

首先,我们需要一个 HTML 元素来承载将要动态显示的文本。为了精确控制打字机效果的作用范围,我们强烈建议为该元素指定一个唯一的 id。在本例中,我们将使用一个

标签,并为其设置 id=”typewriter-text”。

            打字机效果        

请注意,初始时

标签内部可以为空,因为文本内容将完全由 JavaScript 动态生成。

2. CSS 样式:实现闪烁光标

打字机效果的一个重要组成部分是文本末尾闪烁的光标。我们可以通过 CSS 来实现这个效果。我们将利用一个 元素来模拟光标,并通过 CSS 动画使其周期性地改变边框颜色,从而产生闪烁感。

在 JavaScript 中,我们将动态地将这个 元素添加到当前文本的末尾。为了确保它不会被屏幕阅读器误读为实际文本内容,我们还会添加 aria-hidden=”true” 属性。

立即学习“Java免费学习笔记(深入)”;

/* style.css */#typewriter-text {    font-family: monospace; /* 保持等宽字体,使光标位置稳定 */    white-space: nowrap; /* 防止文本换行 */    overflow: hidden; /* 隐藏超出容器的文本,虽然在这里不直接作用于打字机效果 */    display: inline-block; /* 确保h1可以被span撑开 */}#typewriter-text span {    border-right: .05em solid; /* 光标样式:右边框 */    animation: caret 1s steps(1) infinite; /* 应用光标闪烁动画 */}@keyframes caret {    50% {        border-color: transparent; /* 动画50%时,边框变为透明 */    }}

border-right: .05em solid;:创建了一个细长的右边框,模拟打字光标。animation: caret 1s steps(1) infinite;:将名为 caret 的动画应用于光标。1s:动画持续时间为1秒。steps(1):指定动画在一步内完成,这意味着它会立即从一种状态跳到另一种状态,而不是平滑过渡,这对于闪烁效果至关重要。infinite:动画无限循环。@keyframes caret:定义了 caret 动画的关键帧。在动画进行到50%时,光标的边框颜色变为透明,从而实现了闪烁效果。

3. JavaScript 逻辑:核心动画实现

JavaScript 是实现打字机效果的核心。它负责管理要显示的文本内容、逐字输出文本、控制动画速度以及处理文本序列的循环播放。

我们将把所有 JavaScript 代码放在 DOMContentLoaded 事件监听器中,以确保 DOM 完全加载后再执行脚本。

// script.jsdocument.addEventListener('DOMContentLoaded', function(event) {    // 定义要进行打字机效果的文本数组    const dataText = [        "VISIBILITÀ.",        "NUOVI INGAGGI.",        "NUOVI FAN.",        "PIÙ VISIBILITÀ!",        "SUCCESSO!"    ];    const targetElement = document.getElementById('typewriter-text'); // 获取目标元素    /**     * 实现单个字符串的打字机效果     * @param {string} text - 要显示的字符串     * @param {number} i - 当前字符索引     * @param {function} fnCallback - 文本完成时的回调函数     */    function typeWriter(text, i, fnCallback) {        // 检查文本是否已全部显示        if (i < text.length) {            // 将下一个字符添加到目标元素,并附加闪烁光标            targetElement.innerHTML = text.substring(0, i + 1) + '';            // 设置延迟,然后递归调用自身以显示下一个字符            setTimeout(function() {                typeWriter(text, i + 1, fnCallback);            }, 90); // 字符显示速度,单位毫秒        }        // 如果文本已显示完毕,并且存在回调函数        else if (typeof fnCallback === 'function') {            // 在短暂延迟后调用回调函数            setTimeout(fnCallback, 2000); // 文本显示完毕后等待2秒        }    }    /**     * 启动文本数组的打字机动画序列     * @param {number} i - dataText 数组的当前索引     */    function StartTextAnimation(i) {        // 如果当前索引超出 dataText 数组范围,则循环回到第一个文本        if (i >= dataText.length) {            setTimeout(function() {                StartTextAnimation(0); // 循环回到数组开头            }, 20000); // 等待20秒后重新开始整个序列            return; // 结束当前函数执行        }        // 确保 dataText[i] 存在(即不是 undefined)        if (dataText[i]) {            // 开始对当前文本进行打字机动画            typeWriter(dataText[i], 0, function() {                // 当前文本动画完成后,启动下一个文本的动画                StartTextAnimation(i + 1);            });        }    }    // 启动文本动画序列    StartTextAnimation(0);});

代码详解:

dataText 数组: 这是一个包含所有要显示文本的字符串数组。您可以根据需要修改其中的内容。targetElement: 通过 document.getElementById(‘typewriter-text’) 获取到我们之前在 HTML 中定义的

元素,确保 JavaScript 精确地操作目标元素。

typeWriter(text, i, fnCallback) 函数:这是实现单个字符串打字机效果的核心函数。text.substring(0, i + 1):截取从字符串开头到当前索引 i 的子字符串,模拟逐字显示。”:在当前文本末尾添加一个用于显示闪烁光标的 元素。aria-hidden=”true” 确保了辅助技术(如屏幕阅读器)会忽略这个纯粹用于视觉效果的元素。setTimeout(function() { typeWriter(text, i + 1, fnCallback); }, 90);:设置一个定时器,在90毫秒后递归调用 typeWriter 函数,以显示下一个字符。这个延迟决定了打字速度。当 i 等于 text.length 时,表示当前字符串已全部显示完毕。此时,如果提供了 fnCallback(一个回调函数),则在2000毫秒(2秒)后执行它,为用户留出阅读当前文本的时间。StartTextAnimation(i) 函数:这个函数负责管理 dataText 数组中字符串的序列播放。if (i >= dataText.length):检查当前索引 i 是否超出了 dataText 数组的范围。如果超出,说明所有文本都已播放一遍,此时会设置一个20秒的延迟,然后从数组的第一个文本 (StartTextAnimation(0)) 重新开始整个动画序列。if (dataText[i]): 确保当前 dataText[i] 存在,防止因索引越界导致错误(尽管前面的 if 语句已经处理了这种情况,但这是一个良好的防御性编程习惯)。typeWriter(dataText[i], 0, function(){ StartTextAnimation(i + 1); });:调用 typeWriter 函数来显示 dataText 数组中的当前字符串。当 typeWriter 完成其任务后,它会执行提供的回调函数,该回调函数会调用 StartTextAnimation(i + 1) 来启动数组中的下一个字符串的动画。StartTextAnimation(0);: 在 DOMContentLoaded 事件监听器内部,调用 StartTextAnimation(0) 来启动整个打字机动画序列,从 dataText 数组的第一个文本开始。

4. 完整示例代码

将上述 HTML、CSS 和 JavaScript 代码分别保存为 index.html、style.css 和 script.js,并确保它们在同一目录下。

index.html

            动态打字机效果        

style.css

body {    display: flex;    justify-content: center;    align-items: center;    min-height: 100vh;    margin: 0;    background-color: #282c34;    color: #61dafb;    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}#typewriter-text {    font-size: 3em;    font-family: monospace;    white-space: nowrap;    overflow: hidden;    display: inline-block;    border-right: .15em solid orange; /* 初始光标,将被JS中的span替换 */    padding-right: 0.15em; /* 防止文本与光标过于接近 */}#typewriter-text span {    border-right: .05em solid; /* 实际闪烁光标样式 */    animation: caret 1s steps(1) infinite;}@keyframes caret {    50% {        border-color: transparent;    }}

script.js

document.addEventListener('DOMContentLoaded', function(event) {    const dataText = [        "VISIBILITÀ.",        "NUOVI INGAGGI.",        "NUOVI FAN.",        "PIÙ VISIBILITÀ!",        "SUCCESSO!"    ];    const targetElement = document.getElementById('typewriter-text');    function typeWriter(text, i, fnCallback) {        if (i < text.length) {            targetElement.innerHTML = text.substring(0, i + 1) + '';            setTimeout(function() {                typeWriter(text, i + 1, fnCallback);            }, 90);        } else if (typeof fnCallback === 'function') {            setTimeout(fnCallback, 2000);        }    }    function StartTextAnimation(i) {        if (i >= dataText.length) {            setTimeout(function() {                StartTextAnimation(0);            }, 20000);            return;        }        if (dataText[i]) {            typeWriter(dataText[i], 0, function() {                StartTextAnimation(i + 1);            });        }    }    StartTextAnimation(0);});

5. 注意事项与优化

性能: 对于大量文本或复杂动画,innerHTML 的频繁操作可能影响性能。在更复杂的场景中,可以考虑使用 DOM 片段(DocumentFragment)或虚拟 DOM 库。可访问性: aria-hidden=”true” 对光标 的使用是一个很好的实践,因为它确保了屏幕阅读器不会将闪烁的光标读作实际内容。自定义:打字速度: 调整 typeWriter 函数中的 setTimeout 延迟(例如 90 毫秒)可以改变字符显示的速度。文本切换延迟: 调整 typeWriter 函数中回调前的 setTimeout 延迟(例如 2000 毫秒)可以改变每个文本显示完毕后的等待时间。循环延迟: 调整 StartTextAnimation 函数中循环回开头前的 setTimeout 延迟(例如 20000 毫秒)可以改变整个序列重新开始前的等待时间。光标样式: 修改 style.css 中 span 的 border-right 和 caret 动画可以改变光标的外观和闪烁方式。目标元素: 如果需要对多个元素应用打字机效果,可以封装这些函数,使其接受目标元素的 id 或引用作为参数,或者为每个元素创建独立的实例。CSS white-space: nowrap; 和 overflow: hidden;: 这些属性可以防止文本在打字过程中换行或超出容器,保持效果的整洁。

总结

通过结合 HTML 结构、CSS 动画和 JavaScript 逻辑,我们成功创建了一个动态且高度可定制的打字机文本效果。这种效果不仅能增强网页的视觉吸引力,还能有效地引导用户注意力,提升内容的表现力。理解并掌握这些基础技术,将为您的前端开发工作带来更多可能性。

以上就是使用 HTML、CSS 和 JavaScript 创建动态打字机效果的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1525504.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月20日 17:44:22
下一篇 2025年12月20日 17:44:35

相关推荐

  • React Native 应用安装时持久化设置的指南

    本教程详细介绍了如何在React Native应用中,利用AsyncStorage实现应用设置的持久化,尤其侧重于在应用首次安装或启动时加载默认设置,并在用户修改后保存。文章涵盖了AsyncStorage的安装、数据存取、与React Hooks的集成,并提供了完整的示例代码和最佳实践,确保设置在应…

    2025年12月20日
    000
  • 如何安全高效地在React应用中上传文件至MongoDB GridFS

    浏览器出于安全考虑,禁止前端JavaScript直接获取用户本地文件的绝对路径。因此,在React应用中将文件上传至MongoDB GridFS时,不能依赖前端传递文件路径。正确的做法是,前端通过FormData将文件数据以流的形式发送至后端,后端接收文件流后,直接将其管道传输至GridFS进行存储…

    2025年12月20日
    000
  • 深入理解Promise错误处理:为何捕获异常至关重要

    Promise错误处理是前端和后端JavaScript开发中的核心实践。本文将深入探讨为何必须捕获Promise错误,通过对比Node.js和浏览器环境下的不同行为,揭示未处理拒绝的潜在危害,包括导致Node.js应用崩溃和损害浏览器用户体验。文章还将提供正确的错误处理策略,并指出常见误区,旨在帮助…

    2025年12月20日
    000
  • 如何利用JavaScript实现实时数据同步与冲突解决?

    实现实时数据同步与冲突解决需建立WebSocket通信、使用版本号检测冲突,并采用OT或CRDT算法确保一致性,结合本地缓存与乐观更新提升体验。 实现实时数据同步与冲突解决的关键在于监听数据变化、及时传输更新,并在多个客户端修改同一数据时做出合理决策。JavaScript凭借其异步特性和丰富的生态,…

    2025年12月20日
    000
  • 如何实现一个JavaScript的路径规划算法,如A*算法?

    答案:基于JavaScript的A*路径规划算法通过f(n)=g(n)+h(n)评估节点,使用优先队列管理开放列表,结合曼哈顿或欧几里得距离作为启发函数,在二维网格中搜索最优路径;每次扩展f值最小节点,更新邻居代价并维护父指针,最终通过回溯parent生成从起点到终点的路径。 要实现一个基于Java…

    2025年12月20日
    000
  • JavaScript 的异步迭代器和 for-await-of 循环在处理分页 API 时有何优势?

    异步迭代器简化分页处理,通过封装获取下一页逻辑,使调用方无需管理页码或游标,仅用for-await-of遍历即可;其惰性特性实现按需加载,避免资源浪费,适用于大数据量场景;同时统一异步数据流处理方式,提升代码可读性、可维护性和复用性。 在处理分页 API 时,JavaScript 的异步迭代器和 f…

    2025年12月20日
    000
  • jQuery 获取父元素属性时 undefined 的问题解决

    本文针对在使用 jQuery 获取父元素属性时遇到 undefined 的问题,提供了一个清晰的解决方案。通过分析常见错误原因,结合代码示例,详细解释了如何正确地使用 closest() 和 find() 方法来获取目标元素的属性值,避免 undefined 错误的发生。 在使用 jQuery 进行…

    2025年12月20日
    000
  • Vue 3中Axios数据加载与组件挂载时机:解决调度器与DOM错误

    本文深入探讨Vue 3应用中,通过Axios进行异步数据加载时,若未正确处理组件生命周期,可能引发的’error during execution of scheduler flush’和’Cannot read properties of null’…

    2025年12月20日
    000
  • GitHub Pages CSS 未加载:深入解析文件名与路径问题

    GitHub Pages部署后CSS未加载是常见问题,即使本地运行正常。这通常源于本地与远程服务器环境的差异,特别是文件系统对大小写的敏感性,导致SCSS/CSS文件导入路径或文件名不匹配。本文将深入探讨此类问题,并提供详细的排查与解决方案。 在使用github pages发布web项目时,开发者常…

    2025年12月20日
    000
  • 深入理解 Promise 错误处理:为什么你总应该捕获它们?

    即使在看似不必要的情况下,捕获 Promise 错误也至关重要。未处理的 Promise 拒绝可能导致 Node.js(v15及更高版本)应用程序崩溃,并在浏览器环境中引发糟糕的用户体验。主动且恰当地处理错误,不仅能确保应用程序的稳定性,还能为用户提供必要的反馈,避免误导性状态,其意义远超仅仅消除 …

    2025年12月20日
    000
  • 在Next.js项目中启用Webpack的topLevelAwait功能

    本文旨在解决在Next.js项目中启用topLevelAwait实验性功能时遇到的常见困惑。我们将阐明Next.js如何集成Webpack,并提供通过修改next.config.js文件来正确配置topLevelAwait的详细步骤和示例代码,确保开发者能够顺利使用此现代JavaScript特性,避…

    2025年12月20日
    000
  • Discord.js 机器人自动消息发送与缓存管理教程

    本文深入探讨了Discord.js机器人在定时任务中发送自动消息时遇到的常见问题,特别是由于Discord API的缓存机制导致的频道或服务器查找失败。教程提供了使用fetch方法而非cache.get来确保获取最新服务器和频道信息的解决方案,并强调了健全的错误处理和日志记录在调试此类问题中的重要性…

    2025年12月20日
    000
  • 如何构建一个支持边缘计算的Serverless函数?

    选择支持边缘计算的Serverless平台如Cloudflare Workers、AWS Lambda@Edge,设计轻量无状态函数,优化代码体积与执行效率,通过路径或条件配置触发规则,结合CDN与缓存策略降低延迟,并启用日志监控、安全防护与权限控制,确保全球用户低延迟访问。 构建支持边缘计算的Se…

    2025年12月20日
    000
  • jQuery 获取父元素属性时遇到 undefined 的解决方案

    第一段引用上面的摘要本文旨在解决在使用 jQuery 获取父元素特定属性时遇到的 undefined 问题。通过分析问题代码,找出错误原因,并提供正确的 jQuery 选择器用法,确保能够准确获取到目标元素的属性值,从而实现预期的功能。 在使用 jQuery 处理 DOM 元素时,经常需要获取父元素…

    2025年12月20日
    000
  • JavaScript条件语句中的变量作用域与跨函数访问

    本文深入探讨了JavaScript中在条件语句(如if)内部声明变量时可能遇到的作用域问题,以及如何确保这些变量能在不同函数中被正确访问。核心解决方案是在更广阔的作用域(例如全局或父函数作用域)预先声明变量,随后根据条件逻辑进行赋值操作,从而有效避免变量未定义错误,并优化代码的可读性和维护性。 理解…

    2025年12月20日
    000
  • JavaScript中finally方法的括号语法:ES3时代的兼容性解析

    本文探讨了JavaScript中[“finally”]而非.finally()的特殊用法。这种语法源于ECMAScript 3(ES3)的限制,当时像finally和catch这样的关键字无法直接通过点运算符访问,必须使用括号语法。这通常出现在兼容旧版浏览器或遗留代码库中,是…

    2025年12月20日
    000
  • 在 Next.js 项目中启用 Top-Level Await 功能

    本教程旨在解决 Next.js 项目中遇到的 top-level-await 实验功能未启用错误。它将澄清 Webpack 在 Next.js 中的内置机制,并详细指导如何通过修改 next.config.js 文件中的 Webpack 配置来正确启用 topLevelAwait,从而避免创建无效的…

    2025年12月20日
    000
  • JavaScript倒计时持久化:避免页面刷新重置

    本文详细介绍了如何利用浏览器localStorage机制,实现一个在页面刷新后仍能保持其状态的JavaScript倒计时功能。通过在每次倒计时数值更新时将当前值存储到localStorage中,并在页面加载时从localStorage恢复,确保倒计时进程不被中断。文章还提供了完整的代码示例,并包含了…

    2025年12月20日
    000
  • 使用HTML、CSS和JavaScript实现动态打字机效果教程

    本文详细介绍了如何利用HTML、CSS和JavaScript创建引人入胜的动态打字机效果。通过结构化的HTML元素、CSS动画实现光标闪烁,以及JavaScript控制字符逐个显示和文本循环播放,读者将学会如何为网页添加一个专业且富有交互性的文本展示功能,并掌握其核心实现原理和自定义方法。 实现动态…

    2025年12月20日
    000
  • 如何实现一个支持撤销重做功能的状态管理器?

    答案:状态管理器通过历史栈、当前位置和最大长度控制实现撤销重做,每次状态变更保存深拷贝并截断未来历史,撤销时索引前移,重做时后移,支持边界判断与性能优化。 实现一个支持撤销重做功能的状态管理器,核心在于记录状态的历史快照,并提供指针来追踪当前所处的历史位置。关键点是保证操作可逆、状态变更可控,并避免…

    2025年12月20日
    000

发表回复

登录后才能评论
关注微信