如何遍历任何字母数组并通过DOM中的每个字母进行动画处理

问题描述 投票:0回答:1

我正在尝试创建一个打字机效果动画,因此当我在输入框中键入内容时,会显示一条新消息并设置动画效果。

[我试图让全局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>
javascript html dom iterator closures
1个回答
0
投票

使用

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>
© www.soinside.com 2019 - 2024. All rights reserved.