Запускать функцию только один раз до включения - PullRequest
0 голосов
/ 20 июня 2019

У меня есть тег привязки, который воспроизводит звук каждый раз при наведении ссылки:

<a onmouseenter="playAudio();">LINK</a>

Однако при наведении ссылки создают некоторые символы, которые, если я продолжаю перемещать мышь внутри элемента, будут воспроизводить звук снова и снова.

Есть ли способ воспроизвести функцию onmouseenter только один раз, пока не будет обнаружено событие onmouseout?

Я пытался добавить:

<a onmouseenter="playAudio();this.onmouseenter = null;">LINK</a>

но затем он воспроизводит звук только один раз.

А вот и функция анимации TextScramble:

// ——————————————————————————————————————————————————
// TextScramble
// ——————————————————————————————————————————————————

class TextScramble {
  constructor(el) {
    this.el = el
    this.chars = '!<>-_\\/[]{}—=+*^?#________'
    this.update = this.update.bind(this)
  }
  setText(newText) {
    const oldText = this.el.innerText
    const length = Math.max(oldText.length, newText.length)
    const promise = new Promise((resolve) => this.resolve = resolve)
    this.queue = []
    for (let i = 0; i < length; i++) {
      const from = oldText[i] || ''
      const to = newText[i] || ''
      const start = Math.floor(Math.random() * 40)
      const end = start + Math.floor(Math.random() * 40)
      this.queue.push({
        from,
        to,
        start,
        end
      })
    }
    cancelAnimationFrame(this.frameRequest)
    this.frame = 0
    this.update()
    return promise
  }
  update() {
    let output = ''
    let complete = 0
    for (let i = 0, n = this.queue.length; i < n; i++) {
      let {
        from,
        to,
        start,
        end,
        char
      } = this.queue[i]
      if (this.frame >= end) {
        complete++
        output += to
      } else if (this.frame >= start) {
        if (!char || Math.random() < 0.28) {
          char = this.randomChar()
          this.queue[i].char = char
        }
        output += `<span class="dud">${char}</span>`
      } else {
        output += from
      }
    }
    this.el.innerHTML = output
    if (complete === this.queue.length) {
      this.resolve()
    } else {
      this.frameRequest = requestAnimationFrame(this.update)
      this.frame++
    }
  }
  randomChar() {
    return this.chars[Math.floor(Math.random() * this.chars.length)]
  }
}

// ——————————————————————————————————————————————————
// Configuration
// ——————————————————————————————————————————————————

const phrases = [
  'MAIN_HUB'
]

const el = document.querySelector('.link_mainhub')
const fx = new TextScramble(el)

let counter = 0
const next = () => {
  fx.setText(phrases[counter]).then(() => {});
}

el.addEventListener('mouseenter', next);
<a class="link_mainhub" onmouseenter="playAudio();">LINK</a>

Спасибо.

1 Ответ

0 голосов
/ 20 июня 2019

Установите переменную, когда вы начнете воспроизводить аудио, и проверьте это перед повторным воспроизведением.Сделайте, чтобы анимация сбрасывала переменную, когда это сделано.

function audioPlaying = false;
function playAudio() {
    if (!audioPlaying) {
        audioPlaying = true;
        audioEl.play();
    }
}

const next = () => {
  fx.setText(phrases[counter]).then(() => {
    audioPlaying = false;
  });
}
...