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

for循环使用setTimeout实现打字机效果特殊字符显示异常如何修复

JavaScript自定义打字机效果特殊字符重复输出修复方案

问题根因

原代码存在两个核心逻辑问题:

  • for循环为同步执行,会提前按照原始文本总长度生成对应数量的setTimeout定时器。即使在定时器回调内修改i的值,也无法取消已排期的多余定时器,后续多余定时器执行时就会逐个打印特殊字符的编码组成字母。
  • for循环中用let声明的i仅绑定当前迭代作用域,在单个定时器回调内修改的i只是当前回调的局部副本,既不会影响其他已生成定时器绑定的i值,也不会改变循环迭代逻辑。

修复思路

放弃提前批量生成定时器的实现方式,改用递归逻辑:每次打印完当前内容后,再计算下一次需要步进的字符长度、延迟时间,触发下一次打印,完全避免生成多余的定时器。

完整修复代码

function type(fullTxt, currentPos = 0) {
    // 所有需要特殊处理的字符,按长度从大到小排序,避免短字符优先匹配出错
    const specialChars = [
        { str: ' ', length: 6 },
        { str: '<', length: 4 },
        { str: '>', length: 4 }
    ]

    // 已经打印完所有内容,终止递归
    if (currentPos >= fullTxt.length) return

    let step = 1 // 默认每次步进1个字符
    // 匹配特殊字符
    for (const item of specialChars) {
        if (fullTxt.substring(currentPos, currentPos + item.length) === item.str) {
            step = item.length
            break
        }
    }

    // 打印当前内容
    console.log(fullTxt.substring(0, currentPos + step))
    console.log(currentPos) // 对应原代码的j计数
    console.log(currentPos + step - 1) // 对应原代码的i输出
    console.log(fullTxt.length)

    // 延迟300ms触发下一次打印
    setTimeout(() => {
        type(fullTxt, currentPos + step)
    }, 300)
}

// 测试调用
type('hello ')

代码说明

执行上述代码后输出和预期结果完全一致,不会再出现特殊字符编码逐个拼写的问题。如果需要新增其他特殊HTML实体字符,直接往specialChars数组里加对应配置即可,不需要额外编写多分支判断逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:57:04