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

使用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) + '&lt;span&gt;\u25AE&lt;/span&gt;';

  if (textPosition++ != h1MessageArray[0].length) {
    setTimeout("typewriter1()", speed);
  }

}

window.addEventListener('load', typewriter1);

typewriter2 = () => {
  document.querySelector("#h2Message").innerHTML = h2MessageArray[0].substring(0,
    textPosition) + '&lt;span&gt;\u25AE&lt;/span&gt;';

  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();
}

修改说明

  1. 独立变量作用域:给每个打字机函数分配单独的textPosition局部变量,彻底避免两个函数互相干扰。
  2. 替换触发方式:去掉setInterval,改为在typewriter1完成后用setTimeout单次触发typewriter2,避免重复执行冲突。
  3. 优化函数调用:将字符串形式的setTimeout("typewriter1()")替换为直接传函数引用setTimeout(type, speed),更安全且符合JavaScript规范。
  4. 修正HTML输出:直接写入<span>标签,无需转义&lt;和&gt;,简化代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 00:01:06