Alex
Alex

Reputation: 8881

How do I pre-cache images for quick viewing with javascript?

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?

Upvotes: 19

Views: 44145

Answers (10)

Turadg
Turadg

Reputation: 7681

As of Javascript 1.6 this can be accomplished without any named variables:

imageList.forEach( function(path) { new Image().src=path } );

Upvotes: 8

micmcg
micmcg

Reputation: 270

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.

Upvotes: 0

Kon
Kon

Reputation: 27441

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.

Upvotes: 1

Andrew Hedges
Andrew Hedges

Reputation: 21796

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.

Upvotes: 0

dshaw
dshaw

Reputation: 2159

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.

Upvotes: 1

coppro
coppro

Reputation: 14516

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.

Upvotes: 0

Adam Lassek
Adam Lassek

Reputation: 35505

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.

Upvotes: 15

Slartibartfast
Slartibartfast

Reputation: 8805

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.

Upvotes: 3

Diodeus - James MacFarlane
Diodeus - James MacFarlane

Reputation: 114367

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

Upvotes: 40

FlySwat
FlySwat

Reputation: 175593

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');

Upvotes: 1

Related Questions