使用setInterval延迟函数时打字机效果异常的问题求助
问题分析与解决方案
问题描述
尝试使用setInterval延迟第二个打字机函数的执行,但第二个<h2>的打字效果从第4个单词开始,前3个单词被忽略;第一个<h1>的打字效果正常,能从首个字符开始输出。
原代码示例
JavaScript
var h1MessageArray = ["West Sussex Web Design"]; var h2MessageArray = ["Your down-to-earth website designer."]; var speed = 100; var textPosition = 0; typewriter1 = () => { document.querySelector("#h1Message").innerHTML = h1MessageArray[0].substring(0, textPosition) + '<span>\u25AE</span>'; if (textPosition++ != h1MessageArray[0].length) { setTimeout("typewriter1()", speed); } } window.addEventListener('load', typewriter1); typewriter2 = () => { document.querySelector("#h2Message").innerHTML = h2MessageArray[0].substring(0, textPosition) + '<span>\u25AE</span>'; if (textPosition++ != h2MessageArray[0].length) { setTimeout("typewriter2()", speed); } } window.setInterval(typewriter2, 4000);
CSS
#typewriter { width: fit-content; margin: auto; } span { animation: blinker 1s linear infinite; } @keyframes blinker { 50% { opacity: 0; } } @media(max-width:480px) { #typewriter h2 { font-size: 1rem; } }
HTML
<div class="container-fluid mt-5"> <div class="row"> <div class="col-12 text-center" id="typewriter"> <h1 id="h1Message"></h1> <h2 id="h2Message"></h2> </div> </div> </div>
核心问题
两个打字机函数共用了同一个全局变量textPosition:
- 执行
typewriter1时,textPosition会持续累加,直到完成<h1>文本的输出,此时它的值已经等于<h1>文本的总长度。 - 4秒后
setInterval触发typewriter2,此时textPosition不是从0开始,而是直接从之前累加后的数值开始截取<h2>的文本,自然会跳过前面的内容。 - 额外问题:
setInterval会重复触发typewriter2,可能导致多次执行冲突;同时用字符串形式调用setTimeout存在安全隐患且不符合规范。
解决方案
修改后的JavaScript代码
var h1MessageArray = ["West Sussex Web Design"]; var h2MessageArray = ["Your down-to-earth website designer."]; var speed = 100; // 处理h1的打字效果,使用局部位置变量 typewriter1 = () => { let textPosition = 0; const type = () => { document.querySelector("#h1Message").innerHTML = h1MessageArray[0].substring(0, textPosition) + '<span>\u25AE</span>'; if (textPosition++ != h1MessageArray[0].length) { setTimeout(type, speed); } else { // h1完成后延迟4秒启动h2的打字效果 setTimeout(typewriter2, 4000); } } type(); } window.addEventListener('load', typewriter1); // 处理h2的打字效果,使用独立的局部位置变量 typewriter2 = () => { let textPosition = 0; const type = () => { document.querySelector("#h2Message").innerHTML = h2MessageArray[0].substring(0, textPosition) + '<span>\u25AE</span>'; if (textPosition++ != h2MessageArray[0].length) { setTimeout(type, speed); } } type(); }
修改说明
- 独立变量作用域:给每个打字机函数分配单独的
textPosition局部变量,彻底避免两个函数互相干扰。 - 替换触发方式:去掉
setInterval,改为在typewriter1完成后用setTimeout单次触发typewriter2,避免重复执行冲突。 - 优化函数调用:将字符串形式的
setTimeout("typewriter1()")替换为直接传函数引用setTimeout(type, speed),更安全且符合JavaScript规范。 - 修正HTML输出:直接写入
<span>标签,无需转义<和>,简化代码。
内容的提问来源于stack exchange,提问作者Jose
相关产品推荐
相关产品推荐

