JavaScript同步执行问题:多单词逐字显示删除时出现重叠冲突
解决单词动画重叠的问题
你遇到的核心问题是多个单词的动画没有按顺序串行执行——原来的forEach配合固定延迟的setTimeout只是简单延迟了每个单词动画的启动时间,但完全没考虑单个单词完整动画(写入+删除)需要的时长,导致后面的单词提前启动,和前面的动画重叠。
要解决这个问题,我们需要让每个单词的动画彻底完成后,再启动下一个单词的动画。这里可以用Promise和async/await来实现串行流程,重构后的代码如下:
const words_js = document.querySelector('.words-js'); const words = [ 'driven', 'confident', 'creative', 'inspired', 'productive', 'focused', 'fulfilling' ]; // 重构runLetter,返回Promise表示单词动画完成 function runLetter(word) { return new Promise((resolve) => { const letters = [...word]; // 写入字母的逻辑 function writeLetters() { letters.forEach((letter, index) => { setTimeout(() => { words_js.innerHTML += letter; // 所有字母写完后,进入删除阶段 if (index === letters.length - 1) { setTimeout(deleteLetters, 500); // 写入完成后短暂停顿再删除,动画更自然 } }, index * 300); // 可自定义字母间隔时长,这里调小让动画更流畅 }); } // 删除字母的逻辑 function deleteLetters() { for (let i = 0; i < letters.length; i++) { setTimeout(() => { words_js.innerHTML = word.substring(0, word.length - i - 1); // 所有字母删除完后,标记当前单词动画结束 if (i === letters.length - 1) { resolve(); } }, i * 300); } } // 启动写入阶段 writeLetters(); }); } // 用async/await实现串行执行 async function runWords() { for (const word of words) { await runLetter(word); // 单词之间可添加停顿时间 await new Promise(resolve => setTimeout(resolve, 500)); } } runWords();
<span class="words-js"></span>
关键改进点:
- Promise化动画函数:让
runLetter返回一个Promise,只有当单词的写入+删除动画全部完成时才resolve,精准控制每个动画的结束时机。 - 串行遍历单词:用
for...of配合await替代forEach,确保上一个单词的动画完全结束后,再启动下一个单词的动画。 - 优化动画节奏:调整字母间隔时长,增加写入完成后的停顿,让动画过渡更自然。
- 修复拼写错误:原数组里的
condident→confident、fullfiling→fulfilling已修正。
这样修改后,多个单词就会按顺序依次完成写入和删除的动画,不会再出现重叠的问题啦!
内容的提问来源于stack exchange,提问作者Giovanni Poveda
相关产品推荐
相关产品推荐

