Как воспроизводить аудио, нажимая определенную кнопку с onKeyDown на React?

#javascript #html #css #reactjs

#javascript #HTML #css #reactjs

Вопрос:

Я работаю над проектом драм-машины, в котором мне не удается выполнить задачу. задача состоит в том, чтобы:

Когда я нажимаю клавишу запуска, связанную с каждым .drum-pad, должен запускаться аудиоклип, содержащийся в его дочернем элементе (например, нажатие клавиши Q должно вызвать барабанную панель, содержащую строку «Q», нажатие клавиши W должно вызвать барабанную панель, содержащую строку «W»и т.д.).

Мой код до сих пор:

 class Drumset extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.handleKeyPress = this.handleKeyPress.bind(this);
  }
  componentDidMount() {
    document.addEventListener("keydown", this.handleKeyPress);
  }

  handleClick = (event) => {
    const audio = event.target.children[0];
    audio.play();
  };

  handleKeyPress = (event) => {
    if (
      event.key === "q" ||
      event.key === "w" ||
      event.key === "e" ||
      event.key === "a" ||
      event.key === "s" ||
      event.key === "d" ||
      event.key === "z" ||
      event.key === "x" ||
      event.key === "c"
    ) {
      const audio = event.target.children[0];
      audio.play;
      console.log("key pressed");
    }
  };

  render() {
    return (
      <div>
        <div id="drum-machine" class="containerx box-middle">
          <div id="display" onKeyDown={this.handleKeyPress}>
            <div class="container">
              <div class="row">
                <div class="col">
                  <button
                    type="button"
                    class="drum-pad"
                    id="Heater-1"
                    onClick={this.handleClick}
                  >
                    Q
                    <audio
                      class="clip"
                      id="Q"
                      src="https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3"
                      type="audio/mpeg"
                    ></audio>
                  </button>
 

Моя проблема в том, что всякий раз, когда я нажимаю клавишу, функция handleKeyPress() работает, но звук не воспроизводится (консоль показывает печать). Как воспроизводить звук, когда я нажимаю соответствующую кнопку?

Комментарии:

1. audio.play; ничего не делает, просто ссылается на функцию. Ты это имел в виду audio.play() ?

2. @ggorlen получение ошибки в консоли с надписью audio.play() не является функцией всякий раз, когда я запускаю код.

3. @tanjimanim: Ваша проблема решена, используйте ответ, который я предоставил. Также, если вам нужны какие-либо дополнительные объяснения, свяжитесь со мной, брат :). Пожалуйста, примите ответ и оцените его, чтобы другие разработчики могли извлечь из этого выгоду 🙂 Спасибо

4. @ImranRafiqRather спасибо, брат

5. Приветствую, брат. Да благословит вас Аллах 🙂 Пожалуйста, оцените мой ответ и примите его также, нажав на значок галочки. Это будет мотивировать меня больше, а также поможет другим разработчикам с той же проблемой 🙂

Ответ №1:

Проблема заключается в следующем: в вашем handleKeyPress обработчике const audio = event.target.children[0]; он не нацелен на audio элемент.

Я использовал ref таргетинг на звук, как только пользователь нажимает на любую из клавиш, упомянутых в handleKeyPress . Также всякий раз, когда мы используем onKeyDown синтетическое событие, мы должны использовать tabIndex={0} . Попробуйте использовать приведенный ниже код 🙂

 import React, { Component } from "react";

export default class DrumSet extends Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  componentDidMount() {
    document.addEventListener("keydown", this.handleKeyPress);
  }
  handleKeyPress = (event) => {
    console.log(event.key);
    if (
      event.key === "q" ||
      event.key === "w" ||
      event.key === "e" ||
      event.key === "a" ||
      event.key === "s" ||
      event.key === "d" ||
      event.key === "z" ||
      event.key === "x" ||
      event.key === "c"
    ) {
      this.myRef.current.play();
      console.log("key pressed");
    }
  };
  handleClick = (event) => {
    const audio = event.target.children[0];
    audio.play();
  };
  render() {
    return (
      <div>
        <div id="drum-machine" className="containerx box-middle">
          <div id="display" onKeyDown={this.handleKeyPress} tabIndex={0}>
            <div className="container">
              <div className="row">
                <div className="col">
                  <button type="button" className="drum-pad" id="Heater-1">
                    Q
                    <audio
                      className="clip"
                      id="Q"
                      src="https://s3.amazonaws.com/freecodecamp/drums/Heater-1.mp3"
                      type="audio/mpeg"
                      ref={this.myRef}
                    ></audio>
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }
}
 

Комментарии:

1. ну, этот код также выдает мне ошибку «Не удается прочитать свойство ‘play’ null». строка this.myRef.current.play(); вызывает это

2. На моей машине все прошло нормально. Я даже сначала протестировал его.

3. Уважаемый @tanjimanim: Является ли этот компонент частью самого большого проекта или у вас есть только один компонент в вашем приложении. Мы можем написать лучший код, чтобы заставить его воспроизводиться.

4. извините, не заметил эту строку, теперь она работает ref={this.myRef} . кстати, спасибо, что делает tabIndex?

5. tabindex — это просто порядок табуляции. У нас есть клавиша tab на клавиатуре, когда мы нажимаем на нее, фокусируется какой-либо элемент DOM. tabindex=»0″ конкретно означает, что элемент должен быть сфокусирован при последовательной навигации с клавиатуры после любых положительных значений tabindex, а его порядок определяется порядком источника документа.. Поскольку события React — это не события DOM, а синтетические события, рекомендуется использовать tabindex с событием onKeyDown.