使用Javascript的打字效果 - 无法让它模拟打字错误



我剥离了所有内容,并将其放在一个HTML文件中,以便更容易测试这部分内容。

这里的目标是让它首先键入Wx然后删除x等待,然后输入elcome.

代码现在生成welcome,我尝试了很多东西,但不能让它键入带有第一个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>

相关内容

  • 没有找到相关文章

最新更新