JavaScript Image Gallery

This article first appeared in issue 170 of A List Apart Magazine. Here’s a quick and easy way of making a one-page gallery that uses JavaScript to load images and their captions on the fly.

This article first appeared in issue 170 of A List Apart Magazine.

Making an online gallery of pictures should be a quick process. The gap between snapping some pictures and publishing them on the web ought to be a short one. Here’s a quick and easy way of making a one-page gallery that uses JavaScript to load images and their captions on the fly.

Before I show you the JavaScript, let’s start with the mark-up.

I’ve put together some photographs that I want to make into an online gallery. The simplest way of linking to the images is to put them in a list like this:

<ul>
<li><a href="images/bananas.jpg" title="A bunch of bananas on a table">some bananas</a></li>
<li><a href="images/condiments.jpg" title="Condiments in a Chinese restaurant">two bottles</a></li>
<li><a href="images/shells.jpg" title="Seashells on a table">some shells</a></li>
</ul>

Right now, clicking on one of those links leads straight to the image. I’m going to use JavaScript to intercept that click and perform a different action instead.

The JavaScript will dynamically update a placeholder image and description, creating a slideshow effect.

I’m going to use a blank .gif for the placeholder image. I could just as easily use the first image in my gallery or some kind of “intro" image. The important thing is that the image and the description have unique IDs. I’m going to call the descriptive paragraph desc and the image placeholder.

<p id="desc">Choose an image to begin</p>
<img id="placeholder" src="images/blank.gif" alt="" />

Choose an image to begin

Don’t add any height or width attributes to the placeholder image or else all the images in the gallery will be squeezed or stretched to the same size.

Now it’s time to write the JavaScript. This should be placed in the <head> of the document or in an external file. I’ll call the function showPic

function showPic (whichpic)

As you can see, this function will be accepting just one parameter: whichpic. This refers to the link pointing to whichever picture I want to display.

The showPic function is going to be interacting with the desc and placeholder elements by referring directly to their IDs. The first thing I need to do is ensure that this is a capability of the browser executing the function. This is done by checking for the existence of document.getElementById:

if (document.getElementById)

Once the browser passes that test, the placeholder image can be swapped out. This is done by replacing the src value of the placeholder with the href value of the whichpic link:

document.getElementById('placeholder').src = whichpic.href;

At the same time, I want to swap out the text within the desc paragraph. I could use propietary JavaScript such as innerHTML but there’s a cross-browser solution available in the form of childNodes[0].nodeValue. This expression means the value of the first child node of an element. In our case, that will be the text inside the element.

The desc text can be replaced with the text from the whichpic link:

document.getElementById('desc').childNodes[0].nodeValue = whichpic.childNodes[0].nodeValue;

But it would be even better to replace the desc text with the content of the title attribute from the whichpic link:

document.getElementById('desc').childNodes[0].nodeValue = whichpic.title;

I needn’t decide on one arbitrarily. I can test for the existence of a title attribute. If it exists, use that text. Otherwise, use the link text:

if (whichpic.title) {
  document.getElementById('desc').childNodes[0].nodeValue = whichpic.title;
} else {
  document.getElementById('desc').childNodes[0].nodeValue = whichpic.childNodes[0].nodeValue;
}

Lastly, I want to make sure that the whichpic link isn’t actually followed by returning false:

return false;

Unless, that is, the browser didn’t understand document.getElementById. In that case, I do want the link to be followed so true is returned instead.

Here’s the finished function:

<script type="text/javascript" language="javascript">
function showPic (whichpic) {
if (document.getElementById) {
 document.getElementById('placeholder').src = whichpic.href;
 if (whichpic.title) {
  document.getElementById('desc').childNodes[0].nodeValue = whichpic.title;
 } else {
  document.getElementById('desc').childNodes[0].nodeValue = whichpic.childNodes[0].nodeValue;
 }
 return false;
} else {
 return true;
}
}
</script>

All that remains is to call this function from each of the links. In order to pass a value for whichpic, each of the links could be assigned a unique ID. However, it’s much easier just to pass the value this which would mean that whichpic will have the value of “this element calling the function”.

I’ll use the onclick event handler (it would be a good idea to also use onkeypress for people navigating by keyboard). Because the showPic function determines whether the link is actually followed or not, I want the action of clicking the link to return whatever the function returns. If the function returns false, the link isn’t followed. This done by using onclick="return showPic(this)".

<ul>
<li><a onclick="return showPic(this)" href="images/bananas.jpg" title="A bunch of bananas on a table">some bananas</a></li>
<li><a onclick="return showPic(this)" href="images/condiments.jpg" title="Condiments in a Chinese restaurant">two bottles</a></li>
<li><a onclick="return showPic(this)" href="images/shells.jpg" title="Seashells on a table">some shells</a></li>
</ul>

Let’s see it in action.

Choose an image to begin

There you have it: a simple JavaScript image gallery. It degrades gracefully so that older browsers can still follow the links and see the images. It works as expected on IE5+ and Netscape 6+ on Windows and Mac. It also works in Safari and all the various flavours of Mozilla like Firebird and Camino.

You can download the javascript file. Feel free to use it and customise it as you see fit. If you do end up using it, it would be nice if you could drop me a line and let me know where I can see it in action.

Have you published a response to this? :