View Full Version : "Expando" Script, Combining w/ Image Swap

03-13-2009, 12:58 AM
1) Script Title:
2) Script URL (on DD):
3) Describe problem:

Let me begin by saying I LOVE the expando script. Fantastic job.
It works beautifully when applied by itself, but I run into a little problem when I try to combine two effects.

Expando, and the very common Image swap on mouseover.

My basic goal is to have one image there, then on moseover the image swaps for another, and that image expando's.
Then when released, that image should swap back to the original, and expando back down ("contracto").

Now... when I combine them, the first step works fine. But when the mouse is moved away, the image swaps back to the first, but stays big.
Then if that images is mouseover'ed again, it just starts kinda freaking out.

You can view the effect here:

I'd appreciate any help at all any of you can offer. I figure it's probably something simple, right?! :o

The code ends up looking like this:

<script language="JavaScript">
img1_on = new Image(68,50);
img1_off = new Image(68,50);

function over_image(parm_name)
document[parm_name].src = eval(parm_name + "_on.src");
function off_image(parm_name)
document[parm_name].src = eval(parm_name + "_off.src");
<style type="text/css">
img.expando{ /*sample CSS for expando images. Not required but recommended*/
border: none;
vertical-align: center; /*top aligns image, so mouse has less of a change of moving out of image while image is expanding*/

<script type="text/javascript" src="expando.js">
/* Expando Image Script 2008 John Davenport Scheuer as first seen in
http://www.dynamicdrive.com/forums/ username: jscheuer1 */


<a href="http://www.google.com" target="_blank" onmouseover="over_image('img1');" onmouseout="off_image('img1')">
<img name="img1" src="image.gif" width="68" height="50" border="0" class="expando 1">


Thanks for your time!!!!

03-13-2009, 03:34 AM
I did a mod like that already for (see the cartoons at the top):


Here's my mock-up:


In the latter notice the first image (pigs to cruise ship). The rest of the swaps on that page and on loriswebs are less obvious, done only to keep the resolution optimal when the image is small. Use your browser's view source to get the HTML and style code.

The basic idea is that the smaller images are actually background images. You can get the styles from the mockup page. The modified script is here:


I also made up a little inline script to add to the bottom of the page to make sure the larger images were available before the thumbnails become visible:

<script type="text/javascript">
var loadsure = function(i, e){
e = e || window.event || null;
if(e && e.type == 'load' || i.complete){
i.parentNode.className = i.parentNode.className.replace(r2, '');
i.style.visibility = 'hidden';
else i.onload = function(){loadsure(i);};
}, e = document.images, l = e.length, r1 = new RegExp('\\bexpando\\b'), r2 = new RegExp(' start');
for(var i = 0; i < l; ++i)

After studying these examples and the styles and modified code, let me know if you have any questions.

See also this thread:


which is where this was developed.

03-13-2009, 06:00 AM
Your answer was extremely helpful, thank you.
I've got things set up almost perfect...
I just have one more minor issue left with everything.

My eventual goal was to use the effect using images with transparent backgrounds. However using this new method, that means the original (background) image is still visible once the second one expands. Observe here:


Is there a solution to this? I was thinking maybe there's some easy way to tweak the <style> in order to make the background image disappear whenever expanding the 2nd one, then reappear once it shrinks back down.

I appreciate your time and help on this, you're an awesome person. :D

03-13-2009, 06:38 AM
First of all, I don't think you need this:

<script language="JavaScript">
img1_on = new Image(68,50);
img1_off = new Image(68,50);

function over_image(parm_name)
document[parm_name].src = eval(parm_name + "_on.src");
function off_image(parm_name)
document[parm_name].src = eval(parm_name + "_off.src");

because the background images, being smaller will load before the larger images anyway, and neither will be seen until the larger images have loaded. That's what the loadsure (the 'little inline script') script does.

To take care of the issue you are asking about, use this version of the script (additions highlighted):

/* Expando-ZV Image Script 2008 - 2009 John Davenport Scheuer
as first seen in http://www.dynamicdrive.com/forums/
username: jscheuer1 - This Notice Must Remain for Legal Use */

if (document.images){
var cos, times = 40, speed = 20, etype = null;
var expConIm = function(im){
im = im || window.event;
etype = im.type || null;
if (!expConIm.r.test (im.className))
im = im.target || im.srcElement || null;
if (expConIm.cr.test (im.className) && etype == 'mouseover'){
im.getElementsByTagName('img')[0].style.visibility = 'visible';
im.className += ' start';
else if (!im || !expConIm.r.test (im.className))
var e = expConIm,
widthHeight = function(dim){
return dim[0] * cos + dim[1] + 'px';
resize = function(){
cos = (1 - Math.cos((e.ims[i].jump / times) * Math.PI)) / 2;
im.style.width = widthHeight (e.ims[i].w);
im.style.height = widthHeight (e.ims[i].h);
im.style.left = '-' + parseInt(widthHeight (e.ims[i].w)) / 2 + 'px';
if (e.ims[i].d && times > e.ims[i].jump){
im.parentNode.style.zIndex = 3;
e.ims[i].timer = setTimeout(resize, speed);
} else if (!e.ims[i].d && e.ims[i].jump > 0){
im.parentNode.style.zIndex = 2;
e.ims[i].timer = setTimeout(resize, speed);
} else if (!e.ims[i].d && e.ims[i].jump < 1){
im.parentNode.style.zIndex = '';
im.parentNode.className = im.parentNode.className.replace(expConIm.sr, '');
im.style.visibility = 'hidden';
}, d = document.images, i = d.length - 1;
for (i; i > -1; --i)
if(d[i] == im) break;
i = i + im.src;
if (!e.ims[i]){
im.title = '';
e.ims[i] = {im : new Image(), jump : 0};
e.ims[i].im.onload = function(){
e.ims[i].w = [e.ims[i].im.width - im.width, im.width];
e.ims[i].h = [e.ims[i].im.height - im.height, im.height];
e (im);
e.ims[i].im.src = im.src;
if (e.ims[i].timer) clearTimeout(e.ims[i].timer);
e.ims[i].d = !e.ims[i].d;
if(e.ims[i].w && e.ims[i].h)
resize ();

document.write('<style type="text/css">.start { background-position: -1000px!important;}.expando {visibility: visible;}<\/style>');

expConIm.ims = {};

expConIm.r = new RegExp('\\bexpando\\b');
expConIm.cr = new RegExp('\\bexcontainer\\b');
expConIm.sr = new RegExp(' start');

if (document.addEventListener){
document.addEventListener('mouseover', expConIm, false);
document.addEventListener('mouseout', expConIm, false);
else if (document.attachEvent){
document.attachEvent('onmouseover', expConIm);
document.attachEvent('onmouseout', expConIm);

03-13-2009, 07:19 AM
I took out that initial code since yours replaces the need for it.

I'm using Frontpage to do the programming...
The modified js is throwing up a script error on the FP preview...
In IE it didn't seem to change anything.

And in Firefox I think it did the job but it seems a little glitchy.

Are the mods are supposed to make the background image...invisible? To make it go away? Just trying to understand a little better... If I do maybe I can get it working a little better.

Can't thank you enough for all the help.

03-13-2009, 07:50 AM
There shouldn't be any error. FP preview is not really meant for scripts anyway. I'm not sure what you mean by 'glitchy' (though I have been known at times to miss subtle details), it looks fine here to me in FireFox, IE, Safari Win, and Opera.

To answer your question, I'm taking advantage of the start class that was used/created during the page's initialization to hide the thumbnails (which are background images) by setting their position way out of range of the borders of their element. So, when the mouse moves over them, this class name is added again, and their background's effectively disappear so one can see anything underneath them. When the image returns to normal size, this added class name is removed, so you see the background again.

03-21-2009, 03:20 PM

Just wanted to say that I moved the Rubes Cartoons site that is using the expando script to it's own domain so the link above no longer works: