Mr Speaker

Tacky DHTML web tricks #1

Magic trickIt's been a while since we've had some DHTML (Sorry, I mean, DOM scripting) action here, so I thought I'd get us back on track with some stupid DHTML tricks for your web page. Today I'll be showing you the Strongbad-esque technique I've been employing around these parts: hidden popup images.

Have a browse at some of the more recent articles around here. Scan your mouse over all the words. If you find them, pretty images spring to life - adding form and colour to the page. Then, seconds later, they are gone. Leaving you - the reader - intrigued and amused.

So how do you do it?

Well, first some considerations to make popup images practical:

  1. It's got to be easy to add new images. Otherwises it's not gunna happen.
  2. It must provide a method of varying parameters on each image, for added wackiness.
  3. It has to "gracefully degrade" if viewed on browsers that don't support javascript.

First off, I'll show you how I define the popups. This is the only bit you have to change for each image.
<span class="popalots" id="image.jpg_2_100_-100">words here!</span>
Pretty tricky 'eh? I'll break it down for you:

span tag: Every image will be popped-up in response to a mouseover event on the span tag.
class="popalots": To differentiate our pop-ups from regular "spans", we give it our popup class name.
words here!: This is the word/phrase that you want the user to mouseover over. over.
id="image.jpg_2_100_-100": The work-horse of the team - all of our parameters are defined in the id, seperated by underscores. The parameters will be discussed in a tick.

But how?
Put your right hand inOk, thats defining the popup. But how does it work? Well, it's a simple beast to be sure. But to make it even simplier I am using a this nice event manager by Keith Gaughan which takes care of adding events to DOM objects in Mozilla and IE. And cleaning up icky memory leaks too.

We start by define a global array for holding our popup images for preloading. Then add an onload event to the window to do our setup...

var popalot_images = [];
EventManager.Add( window, "load", popalots_setup() );

To add a mouseover event to all the popups, we get every span on the page, then check each one to see if its our popup friend. If it is, add the event:

var spans = document.getElementsByTagName( "span" );
for ( i = 0; i < spans.length; i++ ) {   if ( spans[ i ].className == "popalot" )   {     EventManager.Add( spans[ i ],       "mouseover",       popalots_moused );     ...   } }

Now when a user mouses over one of our popalot spans it will call popalots_moused with the event. To setup our pop up we grab the target of the event, and read the parameters from the id:

var target = e.target ? e.target : e.srcElement;
var popDivId = target.id;
var popParams = popDivId.split( "_" );

The Parameters
Thanks to the split, our popParams variable now contains an array of "parameters" that were defined in the span's id, with each parameter delimited by an underscore. Heres the id format I'm using on my spans:

path|image name_display time_x offset_yoffset

for example:

id="images|popups|popup1.jpg_2.5_100_-100"

This popups up the image "images/popups/popup1.jpg" for 2.5 seconds, 100 pixels right of the mouse and 100 pixels above the mouse.

Poppin' it up
Once we have our parameters, we are ready to add the popup. First create a new div for the image

popDiv = document.createElement( "div" );

Then we set the div's attributes from our popParams array of parameters. Once we are all set up, we add the div to the DOM

var popName = popParams[ 0 ];
var popTime = popParams[ 1 ];
...
document.body.appendChild( popDiv );

At this point, an image will popup when you mouseover the div, but it will just stick around for ever. Annoying if you are trying to read what's underneath it. So we add a timer to get rid of it after a certain amount of time - as specified in the parameters.

setTimeout( "popalota_kill('pop_" + popDivId + "')", popTime * 1000 );

Then our popalota_kill function removes it from the DOM, and we are back to where we started!

var popDiv = document.getElementById( popDivId );
if ( popDiv ) popDiv.parentNode.removeChild( popDiv );

Wow
Yep. Amazing. You can make it nicer though. The script is really straight forward... almost elegant.... I'll put it in a standalone page as a better example. One day. I really like things that use document.getElementsByTagName. I'm going to go see what else I can make with it...

6 Comments

  1. Nice one, and good cameo by mathew krok/lil fat kid/sorbent boy. I personally would have opted for an appearance by this guy.

    Maybe I’ll use your method when I write about a photoshop technique that involves using the move tool to “nudge” a layer.

    Sunday, October 16, 2005 at 11:30 pm | Permalink
  2. My waking life is like this. Bizarre unrelated pop-ups accompanying things i look at. Intriguing AND amusing!

    Thursday, October 20, 2005 at 3:51 pm | Permalink
  3. I can really see an application for this kinda evil in my site… I wonder if you could modify the php script so that everytime a certain word (let’s say Satan or Breasts) appeared it automatically included the span tags around it therefore automatically hotlinking a selection of words with a suitably dumb image. That would be funny

    Monday, December 19, 2005 at 12:20 pm | Permalink
  4. Gah! The fat kid from “Hey Dad!”

    Tuesday, January 10, 2006 at 8:07 am | Permalink
  5. I can understand the sum of the parts… but creating the script for my page.. I’m baffled.

    I would really like to use this script on my site, but I have very limited scripting knowledge apart from ‘put this part here’, ‘change this bit’ and ‘do this ****ake this happen’

    Wednesday, August 30, 2006 at 1:14 pm | Permalink
  6. Hey Allain, when I get a bit of free time today or tomorrow I’ll just make a plain html page that you can copy. The code does get a bit convoluted as my blog has become a javascript maze!

    Thursday, August 31, 2006 at 10:16 am | Permalink
Captcha! Please type 'radical' here: *
How did you find this thingo? *