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
相关产品推荐
相关产品推荐

