Web 页面实现动态逐个字符显示(打字机)效果

Web 页面实现动态逐个字符显示(打字机)效果

普通格式文本

下面是一个完整的示例代码:

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>打字机效果</title>
    <style>
      .typewriter {
        font-family: monospace;
        font-size: 24px;
        margin: 50px;
        overflow: hidden;
        border-right: 2px solid #000;
        white-space: nowrap;
        width: 0;
        animation: typing 4s steps(40, end) forwards, blink 0.75s step-end
            infinite;
      }

      @keyframes typing {
        from {
          width: 0;
        }
        to {
          width: 100%;
        }
      }

      @keyframes blink {
        from,
        to {
          border-color: transparent;
        }
        50% {
          border-color: black;
        }
      }

      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        background: #f0f0f0;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="typewriter" id="typewriter"></div>
    </div>

    <script>
      const text = "欢迎体验打字机效果!";
      const typewriter = document.getElementById("typewriter");

      // 设置初始文本
      typewriter.textContent = text;

      // 如果想要动态逐个字符显示的 JavaScript 版本,可以使用以下代码:
      /*
        let i = 0;
        function typeWriter() {
            if (i < text.length) {
                typewriter.textContent += text.charAt(i);
                i++;
                setTimeout(typeWriter, 100); // 控制打字速度
            }
        }
        typeWriter();
        */
    </script>
  </body>
</html>

这个实现有两种方式:

  1. CSS 动画版本(当前代码中使用的方式):
  • 使用 CSS @keyframes 创建打字和光标闪烁动画
  • 优点:性能好,代码简洁
  • 特点:文字一次性显示完成,带有光标闪烁效果
  • 通过修改 typing 动画的 4s 可以调整打字速度
  1. JavaScript 版本(注释掉的部分):
  • 如果取消注释 JavaScript 部分并注释掉 CSS 的 width 动画
  • 优点:可以更精确地控制每个字符的显示时机
  • 特点:文字逐个字符显示
  • 通过修改 setTimeout100 可以调整打字速度

使用方法:

  1. 将代码保存为 .html 文件
  2. 用浏览器打开即可看到效果

可以根据需要调整:

  • .typewriter 类中的样式(如字体、大小、颜色等)
  • 动画时间(CSS 版本的 4s 或 JS 版本的 100ms)
  • text 变量中的文本内容
  • .container 的样式来调整布局

两种实现方式各有优势,选择哪种取决于具体需求:

  • 如果想要简单的效果,CSS 版本就够用了
  • 如果需要更复杂的控制(如暂停、继续、循环等),可以用 JS 版本

HTML 格式文本

对于 HTML 格式的文本,需要解析 HTML 结构并逐个显示其中的字符,同时保留格式。以下是一个实现方案:

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>HTML格式打字机效果</title>
    <style>
      .typewriter {
        font-family: monospace;
        font-size: 24px;
        margin: 50px;
        width: 300px; /* 控制容器宽度,触发自动换行 */
        word-wrap: break-word;
      }

      .container {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 100vh;
        background: #f0f0f0;
      }

      /* 用于隐藏和显示字符 */
      .char {
        display: inline-block;
        opacity: 0;
      }

      /* 示例格式样式 */
      b {
        font-weight: bold;
      }
      i {
        font-style: italic;
      }
      .red {
        color: red;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="typewriter" id="typewriter"></div>
    </div>

    <script>
      // HTML格式的文本
      const htmlText =
        "欢迎<b>体验</b> <i class='red'>HTML格式</i>的打字机效果";
      const typewriter = document.getElementById("typewriter");

      // 解析HTML并准备字符
      function prepareText(html) {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, "text/html");
        const body = doc.body;

        // 递归处理节点
        function processNode(node, parentElement) {
          if (node.nodeType === Node.TEXT_NODE) {
            // 处理文本节点
            const text = node.textContent;
            text.split("").forEach((char) => {
              const span = document.createElement("span");
              span.className = "char";
              span.textContent = char;
              parentElement.appendChild(span);
            });
          } else if (node.nodeType === Node.ELEMENT_NODE) {
            // 处理元素节点
            const element = document.createElement(node.tagName);
            if (node.className) element.className = node.className;
            parentElement.appendChild(element);
            node.childNodes.forEach((child) => processNode(child, element));
          }
        }

        body.childNodes.forEach((node) => processNode(node, typewriter));
      }

      // 逐字显示
      let index = 0;
      function typeWriter() {
        const chars = typewriter.getElementsByClassName("char");
        if (index < chars.length) {
          chars[index].style.opacity = "1";
          index++;
          setTimeout(typeWriter, 100); // 控制打字速度
        }
      }

      // 执行
      prepareText(htmlText);
      typeWriter();
    </script>
  </body>
</html>

这个实现的主要特点:

  1. HTML 解析

    • 使用 DOMParser 解析 HTML 字符串
    • 递归处理文本节点和元素节点
    • 保留原始 HTML 结构和样式
  2. 逐字显示

    • 将文本节点拆分为单个字符的 span 元素
    • 使用 opacity 控制显示
    • 保持元素间的层级关系
  3. 自动换行

    • 通过 .typewriter 的宽度(width: 300px)控制自然换行
    • 支持复杂的 HTML 结构

使用和调整方法:

  • 修改 htmlText 变量设置 HTML 内容,例如:
    const htmlText = "普通文字<b>粗体</b>和<i>斜体</i>";
    
  • 调整 .typewriterwidth 控制换行位置
  • 修改 setTimeout100 参数调整打字速度
  • 在 CSS 中添加更多样式来支持其他 HTML 标签或类

注意事项:

  • 当前实现支持基本的 HTML 标签和类样式
  • 对于复杂的嵌套结构也能正确处理
  • 如果需要支持更多 HTML 属性(如 style),可以扩展 processNode 函数
posted @ 2025-03-21 14:52  飞仔FeiZai  阅读(405)  评论(0)    收藏  举报