I've tried all manner of methods for accomplishing this and nothing has worked so far. The latest attempt follows. The objective is to call a function that tests for the existence of an image file. If the file exists then that image file is to be displayed. Otherwise, an alternative image file is to be displayed.

So in the body of my page I have a very simple:

<script>
document.write(dispimg());
</script>

Inside the head section is:

function dispimg(){

  var imgtagf="<IMG alt='";
  var imgtagm="Featured Pet' hspace=0 src='gallery/Featured";
  var imgtagb=".JPG' size='medium' border=0>;";
  var imgtag="";

  if (testExists("gallery/Featured.JPG")) {
     alert("file exists"); 
     imgtag=imgtagf+imgtagm+imgtagb; }
  else {
     alert("file does not exist");
     imgtag=imgtagf+"No "+imgtagm+"_None"+imgtagb; }

alert("returning "+imgtag);
  return imgtag;
}

function testExists(imagepath) {
  alert("running testExists");
  req = getreq();
// the following alert never displays
  alert("about to run imageExists");
  req.onreadystatechange = imageExists();
  req.open("head", imagepath, true);
  req.send(null);     
}

function imageExists() {
  alert("running imageExists");
  if(req.readyState == 4) {
     if(req.status == 200) {
        // image exists
        nB=false;
     }
	 else if(req.status==404) {
	    // image doesn't exist
	    nB=true;
	 }
     else {
        // all other error codes will set this
        nB=null;
     } alert("imageExists is "+nB);
     return nB;
  }
}
</script>

As you can see, I've used alerts to see what is getting executed. The function testExists fails almost immediately and I don't know why. Also, I'm not sure if I can do a document.write building the img tag string as I have done which would result in that image displaying in the body where the dispimg function is called.

So I could use some help/education. I am quite the newbie so "speak slowly" :).

MJS

Recommended Answers

All 8 Replies

JavaScript is not designed to access local file due to security; however, Microsoft with ActiveX can access local file system. If you want to know how to do it, you may look at http://www.c-point.com/JavaScript/articles/file_access_with_JavaScript.htm for the way to do it. I am not sure other browsers have created anything like ActiveX...

Actually I'm not trying to access a local file but an image I want to display on my web page (stored in an images folder) but before attempting to load it, I want to verify it's there, and if not, display an alternate image that I can ensure IS there.

Does this alter your response?

MJS

ms_sws,

The only reliable way to test for file existance is to do it server-side in eg PHP, then build the page accordingly.

If server-side programming is not available, then all is not lost because images fire either an onload or an onerror event in response to their src being changed.

Hence, you can attempt to load your preferred image and if onerror fires, load your second preference. Then if onerror fires again go to next preference etc. etc. until eventually a default image is loaded - ie. an image you can guarantee exsits.

Here is one way to formulate the code :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Airshow:: Cascading Image Preferences</title>
<style>
body {  }
</style>

<script>
function cascade_preLoader(imgID) {
	var imgElement = document.getElementById(imgID);
	var basePath = 'gallery/';
	var images = [ //Make this array as long or short as you like
		'featured1.jpg',
		'featured2.jpg',
		'featured3.jpg',
		'default.jpg'
	];
	var currentChoice = -1;
	var preload = new Image();
	preload.onload = function() {
		if(imgElement) { imgElement.src = preload.src; }
	};
	preload.onerror = function() { loadNext(); };
	var loadNext = function() {
		if(++currentChoice < images.length){
			preload.src = basePath + images[currentChoice];
		}
	};
	loadNext();//attempt to preload first image
};
onload = function() {
	cascade_preLoader('myImg');
};
</script>
</head>

<body>

<img id="myImg" src="gallery/default.jpg">

</body>
</html>

This is about as simple as I can make it. A productivity tool such as jQuery may be able to squeeze a few lines out of it but not too many(though I'm sure someone will try).

Airshow

You could actually use Ajax to test if file exist by calling the file on the server side. If the return status is not 200, the file does not exist. If you want to learn about Ajax, you can go http://www.w3schools.com/Ajax/Default.Asp. Hope this would give you another way to do.

You could try to make a img tag put your to_be_tested.jpg to be the source and then you test for the height and width of that tag, if its 0 then the image doesnt exist if not then it exists. But I think it doesnt work in all browsers.
I would suggest looking into php to test your images before displaying, maybe a get_headers functions or something
Good luck to you!

While I haven't tested your solution on my development server (just locally), it works! As is, right "out of the box". I can't tell you how painful it was to get responses and of those received through different forums, one that made good, simple, logical sense; let alone something that actually worked.

I'll follow up when I have a minute to confirm there are no problems running on a server (call me cautious) in case anyone else is looking for a solution like this. But the solution is clean and simple so I can't imagine it not working in a different environment. So thank you and kudos Airshow!

ms_sws,

The only reliable way to test for file existance is to do it server-side in eg PHP, then build the page accordingly.

If server-side programming is not available, then all is not lost because images fire either an onload or an onerror event in response to their src being changed.

Hence, you can attempt to load your preferred image and if onerror fires, load your second preference. Then if onerror fires again go to next preference etc. etc. until eventually a default image is loaded - ie. an image you can guarantee exsits.

Here is one way to formulate the code :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Airshow:: Cascading Image Preferences</title>
<style>
body {  }
</style>

<script>
function cascade_preLoader(imgID) {
	var imgElement = document.getElementById(imgID);
	var basePath = 'gallery/';
	var images = [ //Make this array as long or short as you like
		'featured1.jpg',
		'featured2.jpg',
		'featured3.jpg',
		'default.jpg'
	];
	var currentChoice = -1;
	var preload = new Image();
	preload.onload = function() {
		if(imgElement) { imgElement.src = preload.src; }
	};
	preload.onerror = function() { loadNext(); };
	var loadNext = function() {
		if(++currentChoice < images.length){
			preload.src = basePath + images[currentChoice];
		}
	};
	loadNext();//attempt to preload first image
};
onload = function() {
	cascade_preLoader('myImg');
};
</script>
</head>

<body>

<img id="myImg" src="gallery/default.jpg">

</body>
</html>

This is about as simple as I can make it. A productivity tool such as jQuery may be able to squeeze a few lines out of it but not too many(though I'm sure someone will try).

Airshow

Yep, works as advertised Airshow. Thanks again!

MS

:cool:

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.