Inspired by soundboard sites such as iDaft, I wanted to add audio events to the HTML5 animated menu bar I made in part one of this series. As a rule, I feel that web sites should only “speak when spoken to”, i.e. the majority of web pages should not play audio by default, and leave initiation of playback up to the user. Auto-playing background music on sites makes me angry. I was willing to craft an exception for this example for two reasons: (a) it’s for a music site, in which audio could be reasonably expected to play a part and (b) the code is a proof-of-concept, not an actual site.
Sans Flash or other plugin, we can add sound to a webpage in two ways: either instancing the audio solely through JavaScript, or by embedding the sound on the page with the <audio> tag. In this case, we need to add four sounds: one for each link, with different codecs to cover the current browser incompatibles. Anywhere in the body, I’ll place the following:
- <audio preload="auto" id=harder">
- <source src="assets/audio/harder.mp3">
- <source src="assets/audio/harder.ogg">
- </audio>
- <audio preload="auto" id=better">
- <source src="assets/audio/better.mp3">
- <source src="assets/audio/better.ogg">
- </audio>
- <audio preload="auto" id=faster">
- <source src="assets/audio/faster.mp3">
- <source src="assets/audio/faster.mp3">
- </audio>
- <audio preload="auto" id=stronger">
- <source src="assets/audio/stronger.mp3">
- <source src="assets/audio/stronger.ogg">
- </audio>
Note that we have effectively hidden the sounds on the page by not adding a controls attribute.
I’ll also need to add an id to each link, in order to be able to address them specifically with JavaScript:
- <nav id=equalizer">
- <a href="#" style="left: 20px;" id=beats"><span>Beats</span></a>
- <a href="#" style="left: 170px;" id=samples"><span>Samples</span></a>
- <a href="#" style="left: 320px;" id=loops"><span>Loops</span></a>
- <a href="#" style="left: 470px;" id=rhythms"><span>Rhythms</span></a>
- </nav>
The next part is addressing each audio source and linking it to the mouseover state of each link. I’ll use JQuery to do so, just because it is a little easier to write. In the head section of the page, add:
- <script>
- $(document).ready(function() {
- var harder = $("#harder")[0];
- var better = $("#better")[0];
- var faster = $("#faster")[0];
- var stronger = $("#stronger")[0];
- $("#equalizer a#beats")
- .mouseenter(function() {
- harder.play();
- });
- $("#equalizer a#samples")
- .mouseenter(function() {
- better.play();
- });
- $("#equalizer a#loops")
- .mouseenter(function() {
- faster.play();
- });
- $("#equalizer a#rhythms")
- .mouseenter(function() {
- stronger.play();
- });
- });
- </script>
This works, with a few caveats. Critically, the code is lengthy and heavily repetitious. I’ll clean it up by adding a class to each link that signifies the sound I want to associate with it. The value of that class will match that of the id on the audio tags, so I can cross-reference them easily. So the nav is altered to:
- <nav id=equalizer">
- <a href="#" style="left: 20px;" class="harder"><span>Beats</span></a>
- <a href="#" style="left: 170px;" class="better"><span>Samples</span></a>
- <a href="#" style="left: 320px;" class="faster"><span>Loops</span></a>
- <a href="#" style="left: 470px;" class="stronger"><span>Rhythms</span></a>
- </nav>
And the JavaScript becomes:
- $(document).ready(function() {
- $("#equalizer a")
- .mouseenter(function() {
- var link = $(this);
- var ref = link.attr("class");
- $("#"+ref)[0].play();
- });
- });
The JavaScript could be shortened down even further:
- $("#equalizer a")
- .mouseenter(function() {
- $("#"+$(this).attr("class"))[0].play();
- });
I could make a true graphic equalizer effect with the proposed Web Audio API, but support for that is limited to Firefox at the moment.
There are a few other issues with the menu, mostly to do with browser support for HTML5 audio: depending on the browser version you use, the sound from the first hover may come after a small delay, and the audio clips may not “step” on each other the way one might expect. I’ll address those problems in a future article.
Haha, that is actually incredibly clever.
![Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy] Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]](http://ecx.images-amazon.com/images/I/5192I1rtYnL._SL160_.jpg)

