My goal is to preload these images for an image swap on the page. It runs on body load but I'm not quite sure why it doesn't work...

function preload() {
	imageObj = new Image();
	images = new Array();
	images[0] = "images/globe2.jpg";
	images[1] = "images/stickme2.jpg";
	images[2] = "images/monitor2.jpg";
	images[3] = "images/mail2.jpg";
	images[4] = "images/hyperlink2.jpg";
	for(i = 0; i < 5; i++) {
		imageObj.src = images[i];
	}
}

Dani AI

Generated

Quick summary and practical fix: the common mistake in the original snippet is reusing a single Image instance and not keeping references. When you repeatedly set img.src on the same object earlier loads can be cancelled and the browser may garbage‑collect the object before it finishes. Also avoid global variables and eval() was right to flag that. Use a fresh Image per URL, keep those Image objects in a cache, and bind events with addEventListener rather than inline attributes.

Example: preload into a cache (returns a promise you can wait on)

function preload(urls) {
  const cache = {};
  return Promise.all(urls.map(url => new Promise((resolve, reject) => {
    const img = new Image();
    img.onload  = () => { cache[url] = img; resolve(img); };
    img.onerror = () => reject(new Error('Failed to load ' + url));
    img.src = url;
  }))).then(() => cache);
}

Example: swap on hover using data- attributes (no globals, no eval)

/* HTML example: <img id="logo" src="/images/logo-off.png" data-swap="/images/logo-on.png"> */
preload(['/images/logo-off.png','/images/logo-on.png']).then(cache => {
  const el = document.getElementById('logo');
  const original = el.src;
  el.addEventListener('mouseenter', () => { el.src = el.dataset.swap; });
  el.addEventListener('mouseleave',  () => { el.src = original; });
}).catch(err => console.warn(err));

Troubleshooting tips and notes: declare variables with let/const so you do not pollute globals; use onerror or the promise rejection to catch broken paths; for lots of small icons consider CSS sprites or inline SVG to avoid many requests; for critical visuals consider <link rel="preload" as="image"> (modern browsers) to prioritize network fetch. Mentioning — this pattern will make preloading reliable and avoid flicker or cancelled requests.

Recommended Answers

All 3 Replies

I'm not quite sure why it doesn't work...

Here is a recipe that works.

Thanks a lot fxm! I followed the tutorial and it ended up working great.

For anyone interested this is the code I used:

Javascript:

if (document.images) {
	globeOff = new Image();
	globeOff.src = "images/globe1.jpg";
	globeOn = new Image();
	globeOn.src = "images/globe2.jpg";
}
function turnOn(imgName) {
	if (document.images) {
		document[imgName].src = eval(imgName + "On.src");
	}
}
function turnOff(imgName) {
	if (document.images) {
		document[imgName].src = eval(imgName + "Off.src");
	}
}

HTML:

<a href="#" onMouseOver="turnOn('globe')" onMouseOut="turnOff('globe')">
	<img name="globe" src="images/globe1.jpg" />
	<br />Home
</a>

Thanks a lot fxm!

You're welcome.

document[imgName].src = eval(imgName + "On.src");
document[imgName].src = eval(imgName + "Off.src");

I'm sorry I didn't read all the way through that site.
The calls to eval() it recommends are pointless.

This

document[imgName].src = imgName + "On.src"
document[imgName].src = imgName + "Off.src"

will get the same result.

AAMOF now that I have looked at a range of tutorials on image pre-loading I can say that at best they are wretched [like the one I sent you to :( - sorry again] and at worst they are utterly wrong [like the one you started with].

When I get I few minutes I will post my version here as a snippet.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.