You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现含HTML标签的JS实时打字动画,解决标签字符闪烁问题

问题解析与解决方案

你遇到的<字符闪烁问题,核心原因是当前代码在逐个输出转义后的HTML实体(比如&lt;br&gt;会被拆成&、l、t、;等字符),直到整个实体序列输出完毕,innerHTML才会把它解析成真正的<br>标签,这中间的字符片段就会造成闪烁。不需要提前执行解码函数,而是要调整动画逻辑,避免输出标签的字符片段。

解决思路

把API返回的原始HTML字符串,拆分为纯文本片段和完整HTML标签的组合:

  • 纯文本片段:保持逐个字符输出,保留打字动画效果
  • HTML标签:完整插入DOM,不拆分字符输出,彻底避免显示标签代码

修改后的完整代码

JavaScript

// API返回的原始HTML文本(无需转义,直接用接口返回的text值)
let rawHtml = "<b>Here is some example text</b> followed by line breaks<br><br><br><br><br>and another line break<br><br><b>as well as some bold text.</b>";

// 把HTML拆分为「标签」和「纯文本」的片段数组
function splitHtmlIntoFragments(html) {
  const fragments = [];
  // 正则匹配:要么是完整的HTML标签,要么是标签外的纯文本
  const regex = /(<[^>]+>|[^<]+)/g;
  let match;
  while ((match = regex.exec(html)) !== null) {
    fragments.push(match[0]);
  }
  return fragments;
}

const htmlFragments = splitHtmlIntoFragments(rawHtml);
let fragmentIndex = 0; // 当前处理的片段索引
let charIndex = 0; // 当前文本片段的字符索引
let currentContent = ""; // 已经输出的内容

function typingAnimation(targetId) {
  const targetEl = document.getElementById(targetId);
  if (!targetEl) return;

  setTimeout(() => {
    const currentFragment = htmlFragments[fragmentIndex];
    if (!currentFragment) return;

    if (currentFragment.startsWith("<")) {
      // 当前片段是HTML标签,直接完整添加
      currentContent += currentFragment;
      fragmentIndex++;
    } else {
      // 当前片段是纯文本,逐个字符输出
      if (charIndex < currentFragment.length) {
        currentContent += currentFragment[charIndex];
        charIndex++;
      } else {
        // 文本片段输出完,切换到下一个片段
        fragmentIndex++;
        charIndex = 0;
      }
    }

    // 更新DOM内容
    targetEl.innerHTML = currentContent;

    // 继续动画直到所有片段处理完成
    if (fragmentIndex < htmlFragments.length || charIndex < currentFragment.length) {
      typingAnimation(targetId);
    }
  }, 50);
}

// 跳过动画按钮逻辑
$("#skipAnimationBtn").on("click", () => {
  const targetEl = document.getElementById("typing-animation");
  targetEl.innerHTML = rawHtml;
  fragmentIndex = htmlFragments.length; // 终止动画循环
});

// 启动打字动画
typingAnimation("typing-animation");

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<div id="parent">
  <button id="skipAnimationBtn">点击跳过动画</button>
  <div id="typing-animation"></div>
</div>

CSS

#parent {
  display: block;
}

关键细节说明

  1. HTML片段拆分:用正则/(<[^>]+>|[^<]+)/g精准识别完整的HTML标签和纯文本,确保标签不会被拆分成单个字符输出。
  2. 动画逻辑优化:标签直接完整插入DOM,只有纯文本部分做逐字输出,彻底解决标签字符闪烁的问题。
  3. 跳过动画优化:点击按钮后直接渲染完整的HTML内容,同时终止动画循环,避免后续无效执行。

内容的提问来源于stack exchange,提问作者Mickey Vershbow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:13:15