Skip to content

virtual piano

Irina edited this page Feb 13, 2021 · 2 revisions

Описание задания

Методы поиска элементов

Для поиска элементов используем методы querySelector и querySelectorAll.

Пример
В html-файле контейнер с клавишами имеет класс piano, а клавиши в нём классы piano-key.
Находим элемент с классом piano и записываем его в переменную piano:

const piano = document.querySelector('.piano');

Находим коллекцию элементов с классом piano-key и записываем её в переменную pianoКeys:

const pianoКeys = document.querySelectorAll('.piano-key');

Обратите внимание

  • все переменные, соответствующие элементам, которые есть в коде страницы, объявляются при помощи ключевого слова const
  • также const используется для объявления переменных, которые мы не планируем менять
  • ключевое слово let используется для объявления переменных, значения которых будут изменяться.

События мыши

Метод addEventListener отлавливает событие элемента и выполняет переданную функцию.

Пример 1
При клике по элементу piano вызываем функцию playAudio

piano.addEventListener('click', playAudio);

Пример 2
При клике по элементу piano вызываем функцию playAudio с параметром event:

piano.addEventListener('click', (event) => playAudio);

События клавиатуры

События клавиатуры прослушиваем в глобальном объекте window (окне браузера)

Пример
При нажатии любой клавиши клавиатуры вызываем функцию playAudio :

window.addEventListener('keydown', (event) => playAudio);

Чтобы узнать какая клавиша нажата, используем свойство event.code.
Узнать код клавиши можно на странице https://keycode.info/

Пример
Вызываем функцию playAudio только если нажата клавиша пробел:

window.addEventListener('keydown', (event) => {
  if(event.code === 'Space') {
    playAudio();
  }
});

Проигрывание звука на странице

В html-файл добавим код плеера и кнопку

<audio src="https://zvukipro.com/uploads/files/2017-09/1504526458_zvuki-prirody-penie-solovya.mp3"></audio>
<button>Play audio</button>

В js-файле находим элемент audio, находим кнопку, создаём функцию playAudio, запускаем её при клике по кнопке

const audio = document.querySelector('audio');
const button = document.querySelector('button');

function playAudio() {
  audio.currentTime = 0;
  audio.play();
}
button.addEventListener('click', playAudio)

Обратите внимание

  • названия переменных - существительные, названия функций - глаголы.
  • audio.currentTime = 0; запускает проигрывание с начала трека

Рефакторинг функции playAudio

Создавать отдельный плеер для каждой клавиши пианино означает дублировать код, то есть делать то, чего программисты стараются избежать. На самом деле одного плеера на страницу вполне достаточно, если в функцию playAudio передавать параметр src

<audio></audio>
<button>Play audio</button>
const audio = document.querySelector('audio');
const button = document.querySelector('button');

function playAudio(src) {
  audio.src = src;
  audio.currentTime = 0;
  audio.play();
}

button.addEventListener('click', () => playAudio('https://zvukipro.com/uploads/files/2017-09/1504526458_zvuki-prirody-penie-solovya.mp3'))

Делегирование

Генерал, руководящий боевыми действиями, отдаёт приказы полкам и дивизиям, а не отдельным солдатам.
Если у нескольких элементов должен быть одинаковый функционал, находим их общего родителя и создаём обработчик событий для него одного.
Пример
Добавим обработчик событий элементу piano, затем проверим, является ли элемент, по которому кликнули, его клавишей (имеет ли он класс piano-key) и для этой клавиши запустим функцию playAudio.

const piano = document.querySelector('.piano');

piano.addEventListener('click', (event) => {
    if(event.target.classList.contains('piano-key')) {
      playAudio(src);
    }   
  });

data-атрибуты

data-атрибуты позволяют связать данные с элементами на странице. С их помощью мы можем, например, указать какая нота будет проигрываться при клике по клавише виртуального пианино. Для этого в вёрстке для каждой клавиши пианино указываем data-атрибут с произвольным названием и значением, соответствующим названию музыкального файла, который проигрывается при клике по этой клавише. Пример

<div class="piano-key" data-note="c"></div>

В js-файле находим элемент audio, создаём функцию playAudio в которой указываем audio.src, указываем, что проигрывать нужно с начала трека, запускаем проигрывание.

piano.addEventListener('click', (event) => {
    if(event.target.classList.contains('piano-key')) {
      const note = event.target.dataset.note;
      const src = `assets/audio/${note}.mp3`;
      playAudio(src);
    }   
  });

Подсвечиваем активную клавишу

Для изменения стиля элемента используем метод classList.
Метод classList является идеальным для работы с классами. Он поддерживается всеми современными браузерами.

  • element.classList.add('class'); - добавляет элементу класс;
  • element.classList.remove('class'); - удаляет класс;
  • element.classList.toggle('class'); - переключает класс: добавляет, если класса нет, и удаляет, если он есть. Так как метод classList работает только с классами, то в кавычках внутри может находиться только название класса. И вот перед этим названием класса точка не ставится никогда. Эту ошибку часто совершают начинающие разработчики.

Пример Добавим клавише, по которой кликнули, класс active. Свойства для этого класса указаны в css-файле.

piano.addEventListener('click', (event) => {
  if(event.target.classList.contains('piano-key')) {
    pianoКeys.forEach((el) => {
      if(el.classList.contains('active')) {
        el.classList.remove('active');
      }
    });
    event.target.classList.add('active');
  }
});

Обратите внимание

  • используем делегирование - отслеживаем клик не на каждой клавише, а на их общем родителе
  • event.target- элемент, на котором произошло событие. Проверяем, что кликнули по клавише
  • pianoКeys - все клавиши пианино. Пробегаемся по ним и удаляем класс active, если он есть
  • затем клавише, на которой произошло событие, добавляем класс active