Главная > Аудио, Руководства > Запускаем музыку и звуки событием :hover

Запускаем музыку и звуки событием :hover


17 мая 2011, 14:00. Разместил: Mysterious Master
Если вы забьёте в Google запрос о том, как запустить музыку посредством CSS, вы, вероятно, найдёте:

- Что-нибудь об игре Counter Strike: Source
- Что-нибудь о функциях play-during или cue-before или что-нибудь, что выглядит многообещающе, но в реальности это будет лишь посредственной обучающей статьёй.

Мы не считаем, что различные звуки – это неотъемлемая часть любого веб-сайта, однако обидно, что до сих пор посредством CSS не было возможности запускать звук. Для того чтобы запустить звук, когда курсор мыши попадает в определённую область страницы, нам нужно положиться на HTML5 и/или Flash. Но вряд ли здесь кто-то хочет иметь дело с Flash, правда? Итак, давайте сотворим это посредством HTML5, которая позволяет нам запустить музыку посредством нового элемента «audio» (Firefox 3.5+, Chrome 3+, Opera 10.5+, Safari 4+, IE 9+). Для того чтобы выжать из браузера максимальную возможность, мы реализуем это, используя и источник MP3 (для WebKit и IE) и посредством источника OGG (для Firefox и Opera).

<audio>
        <source src="audio/beep.mp3"></source>
        <source src="audio/beep.ogg"></source>
        Your browser isn't invited for super fun audio time.
</audio>

Если вы вставите код в точности так, как отображено сверху, то вы вряд ли что-то увидите или услышите. Если вам нужен маленький элемент плеера, то обязательно используйте атрибут контроллеров («audio controls»). Если вам надо, чтобы плеер можно было слышать, но не видеть, то воспользуйтесь элементом автоматического запуска («audio autoplay»). Либо используйте оба элемента...

Наша цель – заставить звук воспроизводиться, когда курсор мыши будет наведён на конкретный элемент (например, пункт меню). И опять же, к сожалению, мы не можем заставить элемент «audio» работать посредством CSS, нам надо задействовать javascript. Для того, чтобы проиграть звук посредством javascript, воспользуйтесь кодом:

var audio = document.getElementsByTagName("audio")[0];
audio.play();

// or with an ID

var audio = document.getElementById("mySoundClip");
audio.play();

Давайте воспользуемся jQuery потому, что он значительно упрощает рабочий процесс с выделением и созданием событием.

var audio = $("#mySoundClip")[0];
audio.play();

Давайте сделаем так, чтобы звук начинал играть тогда, когда курсор мыши находился поверх конкретного элемента:

var audio = $("#mySoundClip")[0];
$("nav a").mouseenter(function() {
  audio.play();
});


Другими словами…

Страница тизера мобильного приложения Goodfoot использует похожую технику для вставки звуков, когда вы наводите курсор на голову снежного человека. Здесь всё реализовано посредством внедрения нового элемента audio в DOM при каждом наведении на персонаж:

$("#speak").mouseenter(function(){
        $("<audio></audio>").attr({
                'src':'audio/'+Math.ceil(Math.random() * 5)+'.mp3',
                'volume':0.4,
                'autoplay':'autoplay'
        }).appendTo("body");
});

Это можно немного усовершенствовать до поддержки формата OGG. Не думаем, что атрибут уровня звука будет работать, так как мы ещё нигде не встречали поддержки этой функции. Всё это модернизировал Джеффри Уэй (Jeffrey Way):

function addSource(elem, path) {
  $('<source>').attr('src', path).appendTo(elem);
}

$("#speak").mouseenter(function(){
     var audio = $('<audio />', {
       autoPlay : 'autoplay'
     });
     addSource(audio, 'audio/'+Math.ceil(Math.random() * 5)+'.mp3');
     addSource(audio, 'audio/'+Math.ceil(Math.random() * 5)+'.ogg');
     audio.appendTo('body');
});

Мы удовлетворены таким подходом, так как здесь всё работает так, как надо. После того, как звук воспроизведён, он сохраняется в кэш, что значительно ускоряет работу в следующую загрузку.

Ещё один способ реализации заключается во внедрении трёх аудио-элементов в страницу.

<audio preload="auto" id="sound-1" > ... src & fallback ... </audio>
<audio preload="auto" id="sound-2" > ... src & fallback ... </audio>
<audio preload="auto" id="sound-3" > ... src & fallback ... </audio>

А затем следует поочерёдный выбор каждого из них:

$("#speak").mouseenter(function() {
    $("#sound-" + Math.ceil(Math.random() * 3))[0].play();
});

Повторы и проблемы: накладывание звуков

Изначально некоторые хотят встроить систему в навигационное меню при наведении на вкладки. Здесь сразу открывается проблема: функция .play() запускается гораздо быстрее и чаще, чем вы можете прослушать каждый отдельный запускаемый звук. Один и тот же звук не может быть воспроизведён поверх того, который уже воспроизводится. Поэтому последующие функции .play() не запускаются, пока не первый запущенный цикл не будет закончен.

Изначально мы пробовали воспользоваться функцией .pause() для того, чтобы остановить воспроизведение и запустить функцию снова, но это не помогло. Пауза производится, но затем функция .play() не хочет запускаться заново.

Лучший способ, который мы отыскали – это дублирование элемента для каждого пункта меню. Таким образом каждый пункт меню будет иметь собственный отрезок звукового файла, который будет воспроизводиться по отдельным функциям, создавая наложение.

$("nav a") // loop each menu item
  .each(function(i) {
    if (i != 0) { // only clone if more than one needed
      $("#beep")
        .clone()
        .attr("id", "beep-" + i)
        .appendTo($(this).parent());
    }
    $(this).data("beeper", i); // save reference
  })
  .mouseenter(function() {
    $("#beep-" + $(this).data("beeper"))[0].play();
  });
$("#beep").attr("id", "beep-0"); // get first one into naming convention

Посмотреть демо | Скачать файлы
Внимание! У вас нет прав для просмотра скрытого текста.

Вернуться назад