我实现了循环打字机效果;然而,在第一次遍历数组之后,数组中的第一个单词不会再次被输入。另外,我在最后一个单词之后在第二个单词开始之前收到几个“未定义”。我希望它从第一个单词开始。这是我的代码:
const { useEffect } = React;
const words = ["Business", "Company", "Startup"];
let i = 0;
let a = 0;
let txt = `${words[a]}`;
let speed = 1100;
let loop = true;
function Home() {
const typeWriter = (headerMessage: any) => {
if (i < txt.length) {
headerMessage.innerHTML += txt.charAt(i);
i++;
setTimeout(() => typeWriter(headerMessage), speed);
} else if (loop) {
clearText(headerMessage);
}
}
const clearText = (headerMessage: any) => {
headerMessage.innerHTML = "";
i = 0;
a++;
txt = `${words[a]}`;
if (a > 3) {
a = 0;
}
setTimeout(() => {
typeWriter(headerMessage);
}, 2000);
}
useEffect(() => {
const headerMessage = document.getElementById("header-message");
if (headerMessage) {
typeWriter(headerMessage);
}
}, []);
return (
<main>
<section>
<section>
<div>Let Us Help Grow Your<p id="header-message"></p>.</div>
</section>
<section></section>
</section>
</main>
);
}
ReactDOM.createRoot(document.body).render(<Home />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>
我的想法是将
words
转换为frames
;
['aa', 'bb']
将会是['', 'a', 'aa', '', 'b', 'bb']
然后使用间隔计时器将这些帧放入 dom
const { useEffect, useState } = React;
const words = ["Business", "Company", "Startup"];
const TypeEffect = ({ words }) => {
const [typed, setTyped] = useState('');
useEffect(() => {
const frames = words.map((w) => {
return Array(w.length + 1).fill('').map((item, idx) => w.slice(0, idx))
}).flat();
let frameIdx = 0;
let timer = setInterval(() => {
setTyped(frames[frameIdx]);
frameIdx++;
if (frameIdx === frames.length) { frameIdx = 0; }
}, 200)
return () => clearInterval(timer);
}, []);
return (
<div>{typed}</div>
)
}
function Home() {
return (
<main>
<section>
<section>
<div>Let Us Help Grow Your <TypeEffect words={words}/>.</div>
</section>
<section></section>
</section>
</main>
);
}
ReactDOM.createRoot(document.body).render(<Home />);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>