views:

3638

answers:

9

I have a webpage where I want the user to see a new image when they put thier mouse over a certain part of the image. I used an image map.

<img src="pic.jpg" usemap="#picmap" />
<map id="picmap" name="picmap"><area shape="rect" coords ="10,20,30,40"
onMouseOver="mouse_on_write('mouse is on spot')"
onMouseOut="mouse_off('mouse is off spot')"
href="http://www....html" target="_blank" />
</map>
<p id="desc"></p>

Where in the header I defined these functions:

 <script type="text/javascript">
 function mouse_off(txt)
    {
    document.getElementById("desc").innerHTML=txt;
    document.p1.src="pic.jpg";
    }
 function mouse_on_write(txt)
    {
    document.getElementById("desc").innerHTML=txt;
    document.p1.src="pic2.jpg";
  </script>

It works, but it is slow. When the mouse is put over the second image it takes some few seconds to appear; my temporary solution was to drastically reduce the size of the images because they were huge (at 2.5mb they switch fast now, but still not seamless). How can I make the image switching more seamless without reduction in picture quality? On second thought I realize that I could also just have both images displayed, at a small and a large scale, and on mouse over they would switch places; How would I do this? Would this reduce lag?

A: 

What you want todo is preload the images behind the scenes.

Then, when moused over, the browser will already have that image in its cache and will switch it over very fast.

function preloadImage(imagePath)
{
 var img = document.createElement('IMG');
 img.src = imagePath;  
}

preloadImage('BigImage');
FlySwat
+8  A: 

You don't need to create any page elements, it can all be preloaded using JavaScript:

tempImg = new Image()
tempImg.src="pic2.jpg"

EDIT:

If you have a lot of images, you can use the poor-man's multi-preloader:

preloads = "red.gif,green.gif,blue.gif".split(",")
var tempImg = []

for(var x=0;x<preloads.length;x++) {
    tempImg[x] = new Image()
    tempImg[x].src = preloads[x]
}
Diodeus
+2  A: 

You can also put both images in same file and offset it up and down. If it should affect element you are crossing over with mouse it could look like

a {  
  background-image: url(back.png);  
  background-repeat: no-repeat;  
  background-attachment:fixed;  
  background-position: 0 0;
}

a:hover {
  background-image: url(back.png);  
  background-repeat: no-repeat;  
  background-attachment:fixed;  
  background-position: 0 20px;  
}

This way it can work without javascript.

If I understand your case correctly you still need javascript, but you can "preload" image this way nevertheless.

Slartibartfast
+6  A: 

Doing this with sprites is a good solution, because you don't have to wait to load the new image. Sprites work by combining the two images into one, and changing the background offset on mouseover.

You can even do with with CSS instead, for much faster results. There's a good tutorial on this here.

Adam Lassek
Sprites don't get enough love. Nicely played.
Andrew Hedges
A: 

Use display: none;, then have the Javascript change it to display: inline when you want to display it. This has the added advantage of being able to put the image exactly where you want in the page's source, rather than having to add it with Javascript later.

coppro
A: 

Clever solution from Diodeus. However, unless there's a good reason NOT TO, you should really consider using sprites. It's a bit of work to get them setup, but the net efficiency is really worth it.

This approach is the number one rule in Steve Souder's High Performance Web Sites.

"Rule 1 - Make Fewer HTTP Requests"

Good luck and have fun. - D.

dshaw
While I agree, due to the nature of the questioner it is seems something like sprites could be a bit too challenging.
Diodeus
A: 

Here's how I do it, in pure JavaScript:

var myImgs = ['path/to/img1.jpg', 'path/to/img2.gif'];

function preload(imgs) {
    var img;
    for (var i = 0, len = imgs.length; i < len; ++i) {
        img = new Image();
        img.src = imgs[i];
    }
}

preload(myImgs);

That said, ALassek's suggestion of using CSS sprites is an excellent one, if you have scope to do it. The advantages of sprites are many: fewer HTTP requests, smaller download size (usually), works without JavaScript enabled.

Andrew Hedges
A: 

I've noticed that 'preloading' into .src to this day doesn't work consistently across all browsers - IE7 still can't figure out how to cache / use preloaded images - you can clearly see there's a server request made every time you mouse over.

What I do is load in all images via standard HTML placement and just toggle style.display on and off.

Kon
A: 

http://www.filamentgroup.com/lab/update_automatically_preload_images_from_css_with_jquery/

When we first launched the lab, we released a jQuery plugin that automatically preloads all images referenced in CSS files. We've found the script to be incredibly helpful in developing snappy applications where images are always ready when we need them. This post describes a significant update to the script which will make it even easier to integrate in existing projects.

micmcg