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

如何使用forEach方法让打字效果函数在标题元素数组上依次执行?

解决打字效果依次执行的问题

你的问题在于forEach会同步触发所有的typeEffect调用,每个函数里的setInterval几乎同时启动,所以所有标题的打字效果就撞在一起了。要实现依次执行,我们需要让每个打字效果在上一个完全结束后再开始,这里用Promise配合async/await就能轻松搞定,同时还要先修正原函数里的一个小bug。

步骤1:修复原打字函数的停止逻辑

原代码里的停止条件i === element.length是错误的——一开始元素内容是空的,element.length为0,会直接终止定时器导致打字效果失效。应该改成判断i === str.length,这样当字符全部输出后才清除定时器。

步骤2:将打字函数改为返回Promise

我们把typeEffect改成返回一个Promise,当打字完成时触发resolve,这样就能用await等待它执行结束。

步骤3:用async/await依次执行每个打字效果

不再用forEach同步触发,而是用一个async函数遍历数组,逐个调用typeEffect并等待完成。

修改后的完整代码:

<section id="skills">
  <div class="skills-content">
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
    <h2></h2>
  </div>
</section>
// 获取所有h2元素组成的数组
const skillsHeaders = document.querySelectorAll(".skills-content h2");
// 要应用到标题的内容数组
const skillsHeaderContent = [
  "HTML",
  "CSS",
  "JAVASCRIPT",
  "SASS",
  "GIT",
  "GITHUB",
  "REACT",
];

/**
 * 接收元素和字符串作为参数,在指定元素中逐个字符输出给定字符串
 * @param {Element} element - 目标元素
 * @param {string} str - 要输出的字符串
 * @returns {Promise} 打字完成时resolve
 */
function typeEffect(element, str) {
  return new Promise((resolve) => {
    let typedLetters = "";
    let i = 0;
    const interval = setInterval(() => {
      typedLetters = str.slice(0, i);
      element.textContent = typedLetters;
      // 修正停止条件:当i等于字符串长度时,完成打字
      if (i === str.length) {
        clearInterval(interval);
        resolve(); // 完成后标记Promise为已完成
      }
      i++;
    }, 120);
  });
}

// 依次执行每个打字效果的函数
async function runTypeEffectsSequentially() {
  // 遍历数组,只处理有对应内容的元素(避免h2数量多于内容的情况)
  for (let i = 0; i < skillsHeaderContent.length; i++) {
    const element = skillsHeaders[i];
    if (element) {
      await typeEffect(element, skillsHeaderContent[i]);
    }
  }
}

// 启动依次打字效果
runTypeEffectsSequentially();

为什么这样有效?

  • typeEffect现在返回Promise,只有当打字完成(定时器被清除)时才会resolve,相当于给每个打字效果加了“完成标记”。
  • runTypeEffectsSequentially是async函数,里面的for循环会等待每个await typeEffect(...)执行完毕后,才会进入下一次循环,完美实现了逐个标题依次打字的效果。

另外我加了if (element)的判断,因为你的h2元素有9个,但内容数组只有7个,避免出现找不到对应元素的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:42:32