demosthenes.info

I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter.

featured articles

popular favourites

Electronica Site Navigation, Part 2: HTML5 Audio Events

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:

  1. <audio preload="auto" id=harder">
  2. <source src="assets/audio/harder.mp3">
  3. <source src="assets/audio/harder.ogg">
  4. </audio>
  5. <audio preload="auto" id=better">
  6. <source src="assets/audio/better.mp3">
  7. <source src="assets/audio/better.ogg">
  8. </audio>
  9. <audio preload="auto" id=faster">
  10. <source src="assets/audio/faster.mp3">
  11. <source src="assets/audio/faster.mp3">
  12. </audio>
  13. <audio preload="auto" id=stronger">
  14. <source src="assets/audio/stronger.mp3">
  15. <source src="assets/audio/stronger.ogg">
  16. </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:

  1. <nav id=equalizer">
  2. <a href="#" style="left: 20px;" id=beats"><span>Beats</span></a>
  3. <a href="#" style="left: 170px;" id=samples"><span>Samples</span></a>
  4. <a href="#" style="left: 320px;" id=loops"><span>Loops</span></a>
  5. <a href="#" style="left: 470px;" id=rhythms"><span>Rhythms</span></a>
  6. </nav>

The next part is addressing each audio source and linking it to the mouseover state of each link. I’ll use to do so, just because it is a little easier to write. In the head section of the page, add:

  1. <script>
  2. $(document).ready(function() {
  3. var harder = $("#harder")[0];
  4. var better = $("#better")[0];
  5. var faster = $("#faster")[0];
  6. var stronger = $("#stronger")[0];
  7. $("#equalizer a#beats")
  8. .mouseenter(function() {
  9. harder.play();
  10. });
  11. $("#equalizer a#samples")
  12. .mouseenter(function() {
  13. better.play();
  14. });
  15. $("#equalizer a#loops")
  16. .mouseenter(function() {
  17. faster.play();
  18. });
  19. $("#equalizer a#rhythms")
  20. .mouseenter(function() {
  21. stronger.play();
  22. });
  23. });
  24. </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:

  1. <nav id=equalizer">
  2. <a href="#" style="left: 20px;" class="harder"><span>Beats</span></a>
  3. <a href="#" style="left: 170px;" class="better"><span>Samples</span></a>
  4. <a href="#" style="left: 320px;" class="faster"><span>Loops</span></a>
  5. <a href="#" style="left: 470px;" class="stronger"><span>Rhythms</span></a>
  6. </nav>

And the JavaScript becomes:

  1. $(document).ready(function() {
  2. $("#equalizer a")
  3. .mouseenter(function() {
  4. var link = $(this);
  5. var ref = link.attr("class");
  6. $("#"+ref)[0].play();
  7. });
  8. });

The JavaScript could be shortened down even further:

  1. $("#equalizer a")
  2. .mouseenter(function() {
  3. $("#"+$(this).attr("class"))[0].play();
  4. });

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.

You must be signed up in order to leave comments.

web developer guide

featured comment

by Aisling Brock in New Business Card Design

what i'm reading

A Feast for Crows: A Song of Ice and Fire: Book Four
A Feast for Crows: A Song of Ice and Fire: Book Four

what i'm watching

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]

what i'm playing

Borderlands
Borderlands

what i'm hearing

Planets
Planets

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.