我剥离了所有内容,并将其放在一个HTML文件中,以便更容易测试这部分内容。
这里的目标是让它首先键入Wx
然后删除x
等待秒,然后输入elcome
.
e
的**Welcome**
。
请帮
const element = document.querySelector('#typing-area');
let textToType = 'Welcome';
const delayTime = 1000;
const typingSpeed = 100;
let currentIndex = 0;
function typeLetter() {
const currentText = element.innerHTML;
if (currentIndex === 1) {
element.innerHTML += 'x';
setTimeout(removeX, 1000);
} else {
element.innerHTML = currentText + textToType[currentIndex];
currentIndex++;
if (currentIndex < textToType.length) {
setTimeout(typeLetter, typingSpeed);
}
}
}
function removeX() {
const currentText = element.innerHTML;
element.innerHTML = currentText.slice(0, -1);
currentIndex = 2;
setTimeout(typeLetter, typingSpeed);
}
setTimeout(typeLetter, 500);
#typing-area::after {
content: '';
display: inline-block;
width: 0.1em;
animation: blink 1s infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Typing Example</title>
</head>
<body>
<div id="typing-area"></div>
</body>
</html>
不要修改您的currentIndex (= 2)
,只需添加标记,您已经打印出错误,因此您的下一次迭代继续作为正常文本:
const element = document.querySelector('#typing-area');
let textToType = 'Welcome';
const delayTime = 1000;
const typingSpeed = 100;
let currentIndex = 0;
let hasErrorTyped = false;
function typeLetter() {
const currentText = element.innerHTML;
if (currentIndex === 1 && !hasErrorTyped) {
element.innerHTML += 'x';
setTimeout(removeX, 1000);
hasErrorTyped = true;
} else {
element.innerHTML = currentText + textToType[currentIndex];
currentIndex++;
if (currentIndex < textToType.length) {
setTimeout(typeLetter, typingSpeed);
}
}
}
function removeX() {
const currentText = element.innerHTML;
element.innerHTML = currentText.slice(0, -1);
setTimeout(typeLetter, typingSpeed);
}
setTimeout(typeLetter, 500);
#typing-area::after {
content: '';
display: inline-block;
width: 0.1em;
animation: blink 1s infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Typing Example</title>
</head>
<body>
<div id="typing-area"></div>
</body>
</html>
使用promises让你的代码更清晰
const element = document.querySelector('#typing-area');
const typingSpeed = 100;
type()
async function type() {
await wait(500)
await typeLetters('Wx')
await wait(1000)
await removeLetters(1)
await typeLetters('elcome')
}
function wait(ms) {
return new Promise(r => setTimeout(r, ms))
}
async function typeLetters(letters) {
for (const char of letters) {
element.textContent += char
await wait(typingSpeed)
}
}
async function removeLetters(count) {
for (let i = 0; i < count; i += 1) {
element.textContent = element.textContent.slice(0, -1)
await wait(typingSpeed)
}
}
#typing-area::after {
content: '';
display: inline-block;
width: 0.1em;
animation: blink 1s infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Typing Example</title>
</head>
<body>
<div id="typing-area"></div>
</body>
</html>
您遇到的问题是您每次都只是检查currentIndex === 1
是否正确。第一次运行时,用x
替换e
,每次都是这样。您的解决方案是手动强制索引为2
,这就是跳过字母的原因。请记住,索引从0
开始!
0 - W
1 - e
2 - l
3 - c
5 - o
6 - m
7 - e
所以当你手动强制索引为2
时,这是第一个e
后面的字母,所以它被跳过了。
那么,我在下面所做的只是添加了一些"状态跟踪"使用一个hasTypedError
布尔值,以便输入x
的代码分支只运行第一次。我还将您的currentIndex++
移动到if
语句之外,以便它可以为两个分支增加,并且我固定了removeX
函数中的手动索引重置,现在重置为正确的索引。
const element = document.querySelector('#typing-area');
let textToType = 'Welcome';
const delayTime = 1000;
const typingSpeed = 100;
let currentIndex = 0;
let hasTypedError = false;
function typeLetter() {
const currentText = element.innerHTML;
if (currentIndex === 1 && !hasTypedError) {
element.innerHTML += 'x';
hasTypedError = true;
setTimeout(removeX, 1000);
} else {
element.innerHTML = currentText + textToType[currentIndex];
if (currentIndex < textToType.length - 1 ) {
setTimeout(typeLetter, typingSpeed);
}
}
currentIndex++;
console.log('type', currentIndex, element.innerHTML)
}
function removeX() {
const currentText = element.innerHTML;
element.innerHTML = currentText.slice(0, -1);
currentIndex = 1
setTimeout(typeLetter, typingSpeed);
console.log('remove', currentIndex, element.innerHTML)
}
//Start it all off
setTimeout(typeLetter, 500);
#typing-area::after {
content: '';
display: inline-block;
width: 0.1em;
animation: blink 1s infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
<!DOCTYPE html>
<html>
<head>
<title>Typing Example</title>
</head>
<body>
<div id="typing-area"></div>
</body>
</html>