Christian Heilmann

Dynamic Galleries, real users and Popup Window conditioning

Friday, August 19th, 2005 at 11:53 am

I thought I had done well and created an easy to use, dynamic gallery with DOM and CSS. What it does is show pictures when you click them in the page instead of doing a reload. It also shows a “loading image” message. All feedback I got was positive and I was happy to have provided something slick and useful. Alas, I found out that it is not all like that.

I am currently moving in a new flat and shot some pictures to show around the office, using the dynamic gallery script. I was amazed how many issues my – technically very savvy – colleagues had with the gallery page.

Hitting the right spot

screenshot of user not clicking the image The first confusion point was that a lot of colleagues clicked not the images but the coloured background. It seems that the change of cursor is not neccessarily perceived as the only way to realise what is clickable and what is not. I fixed that by adding the right dimensions to the links, which also allows for hover states:

#thumbs li a{
padding:5px 0;
width:120px;
height:110px;
background:url(roundback.png);
display:block;
}

A Popup is a Popup is a Popup…

The second issue that cropped up shocked me the most. It seems that by showing the image in the page I broke the user pattern of expecting a popup window. Most colleagues actually tried to get the image out of the way to go back to the thumbs by trying to drag the image instead of clicking it to make it disappear. Others even pressed Alt+F4.

Therefore I realised the gallery really needs a force fed information page explaining the functionality before the visitors get to the images . Years of popup window galleries seem to have our visitors conditioned to a certain behaviour. I added a basic message that gets extended should the JavaScript functionality be available.

HTML:

Click the previews to see the big pictures

JS: var closeIntroLink='Go to the pictures'; var closeImageInformation='Click the large picture to close it.'; if(info) { // add the dynamic class to it -> other style info.className=dynamicInfoClass; gallery.className=hideClass; // add the dynamic message and the clink to close it var addinfo=document.createElement('p'); addinfo.appendChild(document.createTextNode(closeImageInformation)) var newa=document.createElement('a'); newa.href='#'; newa.appendChild(document.createTextNode(closeIntroLink)); newa.onclick=function() { this.parentNode.parentNode.removeChild(this.parentNode); gallery.className=''; gallery.getElementsByTagName('a')[0].focus(); return false; } info.appendChild(addinfo); info.appendChild(newa); }

Cache as Cache can

The next problem was MSIE related and drove me bonkers in some other scripts already: Internet Explorer does not fire the onload event on an image when the image is already cached! Furthermore, it does not change the size of the images either. This is also the reason why the gallery script keeps adding and removing the whole image container element rather than just replacing the image in it.

The normal functionality of the script was this:

  • Show the loading message
  • Add the new image
  • If the image is loaded, hide the loading message

Now, if you click on an image and it was loaded and click it again then MSIE will fail to hide the loading message, as the onload never gets triggered. A common way to prevent image caching is to add a random number to the file name, ppk uses that for his image replacement script to check if images can be loaded. In this case this would mean though that the visitors have to load the image every time instead of having a cached copy. Nobody benefits from that. Therefore I put a failsafe in the script by adding a bespoke attribute called “loaded” to the link once the image it links to was loaded.

// if the link does not have a loaded attribute, show the loading
// message
if(!this.loaded)
{
document.getElementById(loadingMessageId).className='';
}
[...]
newpic.onload=function()
{
document.getElementById(loadingMessageId).className=hideClass;
// MSIE won't do setAttribute loaded :-(
this.parent.loaded=true;
}

Even that might fail though, therefore I made sure that when the open image gets closed, the loading message also gets hidden.

Look Mom! No Mouse!

The final problem I found is that the gallery didn’t work with keyboard access. In the article I worked around that by calling the function via the onmousemove handler of the body. This however is not needed, as all that was necessary is to add a real link around the image and shift the focus back and forth between the thumbnail link and the picture via the focus() method. That way you can tab through the thumbnails, press enter to see the image and press enter again to go back to the thumbnails.

New and soon at your door

The updated gallery script now tackles all of these issues and once I am finished unpacking all my crates (anyone want to help carrying?) I will write a follow-up article for devarticles or simply release the script here together with a PHP fallback.

Share on Mastodon (needs instance)

Share on Twitter

My other work: