首页 > 解决方案 > 如何使用 Javascript 中的 forEach() 一次将一个字母连续添加到跨标签

问题描述

我有三个跨度标签,我需要为每个标签添加一些文本,以使其看起来像是被输入到屏幕上。我正在使用 forEach() 循环遍历每个跨度标记并运行一个函数,该函数应该将每个字母一次一个地添加到每个跨度标记中。

但是,forEach 将每个字母同时添加到所有三个跨度标签中。一旦其他两个都添加了所有字母,我只会在最后一个跨度标签上获得所需的“打字”效果。

如何调整 forEach 以使其看起来像是在屏幕上输入文本?请注意,出于样式目的,文本必须位于单独的跨度标签中。

小提琴链接

let delay = 500;
let currentChar = 1;
let idArr = ["firstSpan", "secondSpan", "thirdSpan"];
let textArr = ["heading ", ": ", "'My Book Title'"];

idArr.forEach((item, index) => {

    let text = textArr[index];

    function type() {

        document.getElementById(item).innerHTML = text.substr(0, currentChar);

        currentChar++;

        if (currentChar > text.length) {

            console.log('text length check running')

            currentChar = 1

        } else {

            setTimeout(type, delay);

        }

    }

    type();
})
.cursor {
  color: black;
  animation: 1s blink step-end infinite;
}

@keyframes blink {
  from, to {
    color: transparent;
  }
  50% {
    color: black;
  }
}
<span>
  <span id="firstSpan"></span>
  <span id="secondSpan"></span>
  <span id="thirdSpan"></span>
</span>
<span class="cursor">|</span>

标签: javascripthtml

解决方案


我无法抗拒...

const delay = async(ms) => new Promise(r => setTimeout(r, ms))
  ,   spanN = document.querySelectorAll('#sp3 span')
  ,   txtArr = ['heading ', ': ', 'My Book Title' ]
  ;
async function* LettersSpanGen(aT)
  {
  let SpLt = aT.reduce((r,c,sp)=>[...r,...[...c].map(lt=>({sp,lt}))],[])
  yield* SpLt
  }
(async function()
  {
  for await (let {sp,lt} of LettersSpanGen( txtArr )) 
    {
    spanN[sp].textContent += lt
    await delay(500)
    }
  }
)();
#sp3 span:last-of-type {
  --blinkColor : darkblue;
  color        : var(--blinkColor);
  font-weight  : bold;
  animation    : 1s blink step-end infinite;
  }
@keyframes blink {
  from, to { color: transparent;       }
  50%      { color: var(--blinkColor); }
  }
<div id="sp3">
  <span></span><span></span><span></span><span>|</span>
</div>

任何问题 ?


推荐阅读