A List Apart

Menu
Issue № 170

JavaScript Image Gallery

by Published in HTML, JavaScript · 87 Comments

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.

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="" />

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.

The JavaScript function

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 proprietary 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:

[removed]
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;
 }
}
[removed]

Calling the function

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

Let’s see it in action.


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; 
 } 
}

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 flavors of Mozilla like Firebird and Camino.

87 Reader Comments

Load Comments