如何按顺序执行多个setTimeout 实现逐字符文本解密动画
问题原因
原代码存在两个核心错误导致动画失效:
- 调用
setTimeout时直接写showText()会立即执行showText函数,而非把函数作为延迟执行的引用传给定时器,所有文本更新逻辑直接同步跑完,自然看不到逐字符替换效果。 - 用
var声明的循环变量i是函数作用域,存在变量提升,等定时器异步触发时,循环已经执行完毕,i已经是最终的encText.length+1,所有定时器执行时拿到的都是同一个最终值,无法实现逐位替换。
修复方案
修改后的代码如下:
function play(encText, decrText) { // 优先保证两个文本长度一致,避免显示异常 const maxLength = Math.min(encText.length, decrText.length); for (let i = 0; i < maxLength; i++) { // 传入函数引用而非直接执行,用let的块级作用域保证每个定时器拿到对应位置的i setTimeout(() => { const text = decrText.substring(0, i+1) + encText.substring(i+1); document.getElementById('text').innerHTML = text; }, i * 200); // 毫秒数可自行调整,控制替换速度,原代码5000代表5秒替换一个字符速度过慢 } }
如果需要兼容不支持let的旧环境,也可以用闭包实现相同效果:
function play(encText, decrText) { var maxLength = Math.min(encText.length, decrText.length); function getShowTextFunc(index) { return function() { var text = decrText.substring(0, index+1) + encText.substring(index+1); document.getElementById('text').innerHTML = text; } } for( var i=0; i < maxLength; i++ ) { setTimeout( getShowTextFunc(i), i*200 ); } }
额外说明
- 两个入参
encText和decrText建议保持长度一致,否则超出长度的部分会直接显示加密/解密文本,不会有过渡效果。 - 延迟时长可以根据需要调整,数值越小替换速度越快。
内容的提问来源于stack exchange,提问作者LA_
相关产品推荐
相关产品推荐

