O'Reilly    
 Published on O'Reilly (http://oreilly.com/)
 See this if you're having trouble printing code examples


Author's Note: After additional testing, I've learned that the scripts in this article may not work in some Windows browsers (notably Firefox and Opera) if QuickTime is not installed. For updated scripts, please see Build a Better Web Audio Player. The core ideas are the same, however, so I recommend reading this article first.

There's a newer version of this article: Build a Better Web Audio Player | May 31, 2006

Download tutorial files

In Build a Simple MP3 Player for Your Site, I shared one of my favorite Web tricks: how to make an MP3 link generate a pop-up player when you click it. Why would you want to do that? Normally, when a visitor clicks an audio link (for example, <a href="hit-song.mp3">My Hit Song</a>), the browser blanks out the entire page or launches a helper application. Either result can be jarring to your visitors.

With the pop-up player approach, you add a bit of JavaScript to the link. When the visitor clicks the link, it calls an external JavaScript function that generates a pop-up window containing the audio file and a playback controller. In other words, the JavaScript creates the new window on the fly; you don't have to prepare and upload a separate page for each audio file you want to showcase.

Here's an example, using a music clip from our interview with mixer Tal Herzberg:

If you have JavaScript enabled (most people do), you should have seen a window similar to this:

AudioPop Windows

The audio pop-up audio player as it appears in Windows Internet Explorer with QuickTime installed. See the previous article for the player's other guises.

Visitors with JavaScript turned off (or who right-click the audio link and instruct it to open in a new window) should get the audio file in a new, full-size window.

Getting the Picture

Big Blue Flower Click me.

So far, so good. Our audio links are spawning neat pop-up players instead of booting our visitors off the page. But the flat orange background—or the white one we use for audio pop-ups elsewhere on this site—is rather bland. What if we were to add an image to the pop-up window?

I happened to have a companion script that did just that. It's a variation of the one you may have noticed in O'Reilly's Featured Photographer galleries. When you click on a thumbnail image, the script generates a pop-up window containing a larger version of the photo, plus a title and caption. Try it:

Here's the code for the thumbnail link above:

<a href     = "/images/oreilly/digitalmedia/2005/10/ilachinski-pop.jpg"
   target   = "_blank"
   title    = "Click to see large version"
   onclick  = "javascript:PhotoPop('Big Blue Flower',this.href,'644','523','This image is part of the Featured Photographer profile for Andrew Ilachinski.'); return false">
<img src    = "/images/oreilly/digitalmedia/2005/10/ilachinski-thumb.jpg"
     alt    = "Big Blue Flower"
     width  = "106"
     height = "86"
     border = "0" />
</a>

Note how the main HTML portion of the link is a simple image reference and target attribute. That's the part that will fire if the visitor has JavaScript disabled. The JavaScript portion of the link, following the onclick handler, calls the function PhotoPop, which is stored in an external JavaScript file. The link passes five pieces of data to the external function:

  1. The pop-up window title (Big Blue Flower)
  2. The URL of the large image (this.href, which refers back to the image URL in the HTML portion of the link)
  3. The width of the large image
  4. The height of the large image
  5. The caption that will appear in the pop-up window

Immediately following that collection of data is the statement return false, which prevents the HTML portion of the link from firing after the JavaScript does. If we left that statement out, clicking the link would open both the pop-up window and a new regular window containing the large image.

Typing up that long, twisted link would be a pain, so I wrote a Dreamweaver extension to do it for me. You can download the extension at the beginning or end of this article. Once it's installed in Dreamweaver, all you have to do to create a pop-up image link is select Batmo_Image_Pop from Dreamweaver's Insert menu and fill in the form that pops up. It will look something like this:

Image Pop Form To create the complex JavaScript pop-up link above, all I did was fill out this form and hit OK. You can download this Dreamweaver extension at the end of the article. You'll also need to install the external JavaScript file called pop-up-scripts.js, available in the same download, and insert a link to it in the page on which you want to use the pop-up link.

Sound and Vision: The Enhanced MP3 Player

The final step is to combine the audio and image scripts into a single entity and stylize the window. I decided to add a black border to the image and a texture to the window's background. I also worked out a way to adjust the window's height to accommodate the length of the caption. And I added one new data item to the link: a variable called UniqueID that prevents new windows from opening when you click the same link repeatedly.

The seven variables in the link are popuptitle, imgpath, imgwidth, imgheight, caption, soundpath, and UniqueID. Here's an example of the enhanced audio pop-up player with short and long captions:

The Angel

Click me (short caption).

The Angel

Click me (long caption).

Here's the code in the external JavaScript file that makes it work. The winWidth and rawHeight lines set the size of the pop-up window, based on the size of the graphic and the length of the caption it will contain. I derived the formula for calculating the height of the caption through experimentation. It counts the number of characters in the caption variable, then converts that to pixels. (More or less—if you have lots of HTML character codes in the caption, such as &#8212;, the em-dash (—), it will throw off the length.)

The next line, with the math functions, rounds the calculated height to a whole number, because I discovered that Safari couldn't deal with fractional pixels. After that comes the pop-up and embedding code described in Build a Simple MP3 Player for Your Site. To create the metallic background, I used a 650x1-pixel gradient as the background tile for the window.

// Pop-Up Audio/Photo Embedder Script by David Battino, www.batmosphere.com
// v 2005-10-04
// OK to use if this notice is included
function EnhAudioPop(popuptitle,imgpath,imgwidth,imgheight,caption,soundpath,UniqueID) { // Add error handling?
    var winWidth  = Number(imgwidth) + 100;
    var rawHeight = Number(imgheight) + 168 + caption.length/7; // calculate window height based on caption length
    var winHeight = Math.round(rawHeight * Math.pow(10,0))/Math.pow(10,0); // round to integer
    
    MediaWin = window.open('',UniqueID,'width=' + winWidth + ',height=' + winHeight + ',top=0,left=0,resizable=1,scrollbars=0,titlebar=0,toolbar=0,menubar=0,status=0,directories=0,personalbar=0');
    MediaWin.focus();
    
    var winContent = "<html><head><title>" + popuptitle + "</title></head>";
    winContent += "<body bgcolor='#9E9E9E' background='/images/oreilly/digitalmedia/2005/10/metal_tile.jpg'>"; // check image path
    winContent += "<div align='center'>";
    winContent += "<br /><br />"; // could use CSS padding instead
    winContent += "<img src='" + imgpath + "' id='image1' border='2' alt='" + popuptitle + "' width='" + imgwidth + "' height='" + imgheight + " 'title='" + popuptitle + "' />";
    winContent += "<br />";
    winContent += "<object width='" + imgwidth + "' height='42' >";
    winContent += "<param name='src' value='" + soundpath + "'>";
    winContent += "<param name='autoplay' value='true'>";
    winContent += "<param name='controller' value='true'>";
    winContent += "<param name='bgcolor' value='#9e9e9e'>";
    winContent += "<embed src ='" + soundpath + "' autostart='true' loop='false' width='" + imgwidth + "' height='42' controller='true' bgcolor='#9e9e9e'>";
    winContent += "</embed></object>";
    winContent += "<div style='width: " + imgwidth + "px; margin: 0px; padding: 0px; text-align:left;'>"; // restrict caption width to image width
    winContent += "<p style='font-size:12px;font-family:Verdana,sans-serif'>" + caption + "</p>";
    winContent += "</div>";
    winContent += "<p style='font-size:12px;font-family:Verdana,sans-serif'><a href='" + soundpath + "'>Download audio file</a> <span style='font-size:10px'>(right-click or Option-click)</span>";
    winContent += " &#8226; <a href='#' onClick='javascript:window.close();'>Close this window</a></p>";
    winContent += "</div>";
    winContent += "</body></html>";

    MediaWin.document.write(winContent);
    MediaWin.document.close(); // "Finalizes" new window
}

Enhancing the Enhancement

I hope to use this idea for a new batch of audio articles that will expand on our Featured Photographer series. For example, instead of a gallery of pop-up images, we could show the steps in recording a song, with an image and audio example for each step. For that, it might be handy if each pop-up window could call the previous or next one on the series. O'Reilly's Mark Levitt, who gave me a lot of ideas for this article, thinks the easiest way to do that would be to store all the data for each pop-up window in an array. Let us know if you come up with any other ways to enhance these enhancements. You can download the JavaScript file and Dreamweaver extension here.

Pop to it!

Copyright © 2009 O'Reilly Media, Inc.