我正在尝试创建一个打字机效果动画,因此当我在输入框中键入内容时,会显示一条新消息并设置动画效果。
[我试图让全局char变量遍历数组的每个元素,但是当我要传递另一个字母数组时,在输入框中键入文本后,h1不会被覆盖。
这是我的尝试
// wrap each letter in output in a span
function createInduvidualLetterSpans(letterArr) {
if (textEl.innerHTML) {
textEl.innerHTML = ''
}
for (const letter of letterArr) {
const letterEl = document.createElement('span')
letterEl.textContent = letter
textEl.appendChild(letterEl)
}
return textEl
}
// animate each letter
let char = 0
function displayChars() {
const span = textEl.querySelectorAll('span')[char]
span.classList.add('load')
char++
if (char == textArr.length) {
complete()
return
}
}
function complete() {
clearInterval(timer)
timer = null
}
createInduvidualLetterSpans(textArr)
let timer = setInterval(displayChars, 10)
我的下一个尝试是尝试迭代器和闭包。我一直在阅读这些想法,并立即认为这对他们来说将是一个完美的用例。但是,我得到了要动画显示的文本,但是我得到了
span is unidentified
错误,我不确定为什么。
//turn text into an array of letters
const textEl = document.querySelector('h1')
const textArr = textEl.textContent.split('')
const explore = 'Your lack of desire has lead you towards a life of bordeom and dread. [[GAME OVER]]'.split('')
const userInput = document.getElementById('user-input')
textEl.textContent = ''
// iterator fn
function iterator(arr) {
let count = 0
const inner = {
next: function () {
const el = arr[count]
count++
arr[count] == undefined ? done = true : done = false
return {
value: el,
done
}
},
createSpan: function (letterArr) {
textEl.textContent = ''
for (const letter of letterArr) {
const letterEl = document.createElement('span')
letterEl.textContent = letter
textEl.appendChild(letterEl)
}
},
animateEachLetter: function () {
const span = textEl.querySelectorAll('span')[count]
span.classList.add('load')
count++
arr[count] == undefined ? done = true : done = false
}
}
return inner
}
const it = iterator(explore);
it.createSpan(explore)
const exploreRoom = () => {
it.createSpan(explore)
}
exploreRoom()
setInterval(it.animateEachLetter, 10)
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
}
body {
max-width: 100%;
}
span {
opacity: 0;
}
span.load {
opacity: 1;
}
<div class="grid">
<h1>You wake, confused and disoriented. Something just does not feel quite right. You reach over to the night stand, find a pair of glasses, put them on (even though you do not wear glasses and stand up. Do you explore the room or go back to bed?</h1>
<form id="user-input">
<input id="user-text" class="input" type="text" name="text" autofocus>
</form>
</div>
使用
setInterval(it.animateEachLetter, 10)
和
animateEachLetter: function () {
const span = textEl.querySelectorAll('span')[count]
span.classList.add('load')
count++
arr[count] == undefined ? done = true : done = false
}
您正在调用animateEachLetter
并尝试查找span
,更改其类并递增计数。听起来您只需要检查是否首先存在这样的跨度-如果不存在,请清除间隔。迭代器协议使事情变得比需要的混乱得多,您可以考虑将其完全删除。
另外,您的animateEachLetter
实际上是为单字母而不是每个字母设置动画。考虑有一个animateEachLetter
方法实际上对每个字母进行动画处理,然后调用different方法(在间隔中运行的方法)对one字母进行动画处理:
const textEl = document.querySelector('h1');
const textArr = textEl.textContent.split('');
const explore = 'Your lack of desire has lead you towards a life of bordeom and dread. [[GAME OVER]]'.split('');
const userInput = document.getElementById('user-input');
function makeAnimator(arr) {
let count = 0;
return {
createSpan: function(letterArr) {
textEl.textContent = '';
for (const letter of letterArr) {
const letterEl = document.createElement('span');
letterEl.textContent = letter;
textEl.appendChild(letterEl);
}
},
animateEachLetter(ms) {
this.interval = setInterval(() => this.animateOneLetter(), ms);
},
animateOneLetter() {
const span = textEl.querySelectorAll('span')[count];
if (!span) {
clearInterval(this.interval);
return;
}
span.classList.add('load')
count++
arr[count] == undefined ? done = true : done = false
}
};
}
const animator = makeAnimator(explore);
animator.createSpan(explore)
animator.animateEachLetter(20);
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
}
body {
max-width: 100%;
}
span {
opacity: 0;
}
span.load {
opacity: 1;
}
<div class="grid">
<h1>You wake, confused and disoriented. Something just does not feel quite right. You reach over to the night stand, find a pair of glasses, put them on (even though you do not wear glasses and stand up. Do you explore the room or go back to bed?</h1>
<form id="user-input">
<input id="user-text" class="input" type="text" name="text" autofocus>
</form>
</div>