最直接可靠的单行打字机效果用 setinterval 实现:通过 textcontent 安全追加字符,计数器从 0 开始用 slice(0, i) 截取,避免 xss 和重复;不可用 settimeout 递归或 css 动画。

用 setInterval 逐字追加最直接可靠
单行打字机效果本质就是按时间间隔往元素里塞字符,setInterval 是最可控的方式。别用 setTimeout 递归或 CSS 动画模拟,前者容易失控,后者无法精确控制光标节奏或中途暂停。
关键点:
-
textContent比innerHTML更安全,避免 XSS 风险,除非你明确需要解析 HTML 标签 - 必须提前获取目标元素,否则
innerText或textContent读取为空时会出错 - 计数器从
0开始,截取字符串用str.slice(0, i),不是str.substring(0, i+1)—— 容易多写一位导致重复
const el = document.getElementById('typewriter');
const text = 'Hello world!';
let i = 0;
const timer = setInterval(() => {
if (i
<h3>加闪烁光标得用 <code>::after</code> 伪元素,别用 <code>|</code> 字符硬拼</h3>
<p>用纯字符 <code>|</code> 做光标会干扰复制、选中和屏幕阅读器,且在不同字体下宽度不一致。CSS 伪元素才是标准解法。</p>
<p>注意细节:</p>
- 光标颜色要和文字一致,用
color: currentColor继承父级颜色,避免写死 - 动画必须用
opacity+animation,不能靠 JS 切换类名——否则和打字节奏不同步 - 伪元素内容设为空
content: '',否则可能触发布局重排
#typewriter {
position: relative;
font-family: monospace;
}
#typewriter::after {
content: '';
position: absolute;
right: -5px;
top: 50%;
transform: translateY(-50%);
width: 1px;
height: 80%;
background-color: currentColor;
animation: blink 1s infinite;
}
@keyframes blink {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
中途停止或重播要清理定时器并重置状态
如果用户点击按钮暂停,只调 clearInterval(timer) 不够——下次再播会从上次断点继续,而不是从头开始。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
正确做法是把定时器 ID 和计数器都封装成可复用的状态对象:
- 每次启动前先清掉旧定时器(即使没运行,调用
clearInterval也无副作用) - 重置
i = 0,再重新赋值el.textContent = '',否则残留文字会影响新文本渲染 - 不要把
timer声明为全局变量,多个打字机实例会互相覆盖
let typewriterState = { timer: null, i: 0 };
function startTyping(el, text, delay = 100) {
clearInterval(typewriterState.timer);
typewriterState.i = 0;
el.textContent = '';
typewriterState.timer = setInterval(() => {
if (typewriterState.i
<h3>移动端要注意 <code>requestAnimationFrame</code> 不适合这类固定节奏效果</h3>
<p>有人想用 <code>requestAnimationFrame</code> 替代 <code>setInterval</code> 来“更流畅”,但这是误解。<code>requestAnimationFrame</code> 节奏取决于屏幕刷新率(通常是 60fps),而打字机需要稳定的时间间隔(比如每 100ms 打一个字),两者目标完全不同。</p>
<p>实际影响:</p>
- 低端安卓机上
requestAnimationFrame可能掉帧,导致打字忽快忽慢 - 后台标签页中
requestAnimationFrame会被节流甚至暂停,setInterval虽然也会降频,但至少能保证最终完成 - iOS Safari 对
setInterval的最小间隔限制是 4ms,100ms 完全安全
真正该优化的是光标闪烁动画:用 will-change: opacity 提升合成层,避免触发重排重绘。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










