blog | bio | agenda | jobs | ajaxCFC

HTML OnMissingImage

Scenario: you need to display a bunch of images but you're not 100% certain that they exist.

Solution 1: If the images are hosted in the same server you can loop over their physical path display an alternate image if the image was not found on disk. This solution is very taxing (I/O intensive) and not efficient at all. It also won't work if you're not hosting the images.

Solution 2: What now? I found a few JavaScripts to loop over every image found in the DOM and check of http status, then replace them if the image wasn't loaded properly. This solution is much better because it's decentralized and the load is delegated to the client as opposed of the server, and it also works with images hosted elsewhere.

Solution 3 (winner): Did you know that the image tags have an onError attribute? I can't believe that after 15 years of web development I just found out about this now :) ... This is the optimal solution as it is native to the browser, works on every browser (I tested IE6+, FF2.0+, Safari1.3+, all on Mac and PC).

Check it out, I included two images: img01.gif, which exists on my server, and img02.gif. Both of them have an onerror attribute with a simple script: this.src=error.gif.

img02.gif does not exist on my server, consequently the script will be executed and load my error.gif
<img src="img01.gif" width="100" height="100" onerror="this.src='error.gif';">
<br clear="all">
<img src="img02.gif" width="100" height="100" onerror="this.src='error.gif';">



So simple and yet so powerful. Enjoy.

TrackBacks
There are no trackbacks for this entry.

Trackback URL for this entry:
http://www.robgonda.com/blog/trackback.cfm?6F36F871-B332-AF2B-5E6B823579B1F028

Comments
Thanks for this, it has been useful in a project I'm working on... sweet!
# Posted By Chris Dawes | 4/21/08 1:53 AM
You're kidding. I'd never heard of this! I'd always used the If FileExists which as you point out isn't optimal from a performance perspective. Will have to use this in my future projects!
# Posted By Peter Bell | 4/21/08 8:33 AM
Wow Rob, I can't believe how perfectly timed this is. I was honestly thinking of this very issue this morning - and since the images in my case are being displayed in a Spry dynamic region this solution should work perfectly! Thanks man!!
# Posted By todd sharp | 4/21/08 8:36 AM
FYI...send entry seems to not be working?
# Posted By todd sharp | 4/21/08 8:36 AM
Well I'll be damned... Thanks, Rob!
# Posted By Christian Ready | 4/21/08 8:54 AM
This makes me want to go review the HTML docs. Anyone know a good place for a basic HTML reference?
# Posted By Raymond Camden | 4/21/08 9:11 AM
Very cool. Makes ya wonder what other neato things are locked deep in the HTML spec, etc...
# Posted By Dave Taylor | 4/21/08 9:15 AM
@Ray: I would have said W3C - but I checked it when I read this post and there was no mention of using onError with <img>
# Posted By todd sharp | 4/21/08 9:56 AM
@Todd, I disabled the send functionality until I add captcha cuz I was getting spammed. Will be back in the next couple of days.

@Ray, w3c would be the place, but like Todd mentioned, it seems like it's not explicitly mentioned there. However, I found this reference to it at http://www.w3schools.com/jsref/jsref_onError.asp
# Posted By Rob Gonda | 4/21/08 10:17 AM
This is amazing, like you I can not believe this is the first I am hearing about it.
# Posted By Dan Vega | 4/21/08 10:21 AM
@Rob - The latest BlogCFC will use CAPTCHA for send if it is enabled. ;)

Also, if you disable white space suppression on the server it will make your comment emails a bit nicer - or - and this is NOT checked in to blogcfc yet, wrap the comment text with a <cfprocdir> that disables whitespace supression.

It is a small thing, but boy does it makes the comment emails easier to read.
# Posted By Raymond Camden | 4/21/08 10:32 AM
@Ray, I know ... still meaning to upgrade to the latest ver... that's why I asked you about 5.9 vs 6.0. I'll try to upgrade in the next few days. Thanks for BlogCFC
# Posted By Rob Gonda | 4/21/08 10:53 AM
Now if this attribute were supported via CSS, that would rock. Otherwise, adding that onError attribute to EVERY <img> tag in your HTML would certainly increase the bloat...
# Posted By Will B. | 4/21/08 11:48 AM
So I tried this within a Spry dynamic region, and it's not working so hot. It replaces *every* image, even good ones. I'm guessing the onerror fires immediately, and since the img path is dynamic and dependent upon the ajax data it is not finding the image so it immediately replaces it. Unfortunately, by the time the dynamic region is updated it's too late (and doesn't fire again)... :(
# Posted By todd sharp | 4/21/08 11:55 AM
Hopefully Rob won't mind me hijacking this thread a bit. Hey Todd, I bet you could use Spry's event handlers to notice when the region is done drawing, loop over the data, check the http status, and then replace the images. That would be a good blog post perhaps.
# Posted By Raymond Camden | 4/21/08 11:59 AM
Good idea Ray. Here's what I came up with for others who may need the solution:
http://cfsilence.com/blog/client/index.cfm/2008/4/...
# Posted By todd sharp | 4/21/08 12:51 PM
Thanks SO much Rob.
I spent part of last friday puzzling over a very slow "cfhttp" error-checking process that I developed for a site where we have the (vehicle listing) data in-hand, but no indication how many images each one has in the data (or if it has one at all) and all of the images are hosted remotely. My next step was going to be a nightly massive loop / check / copy process for a gazillion jpgs and thumbnails, and even then I would have to check for the file existing on our own server after they'd all been copied over... this method will be MUCH better!

Like somebody else said in an earlier comment, it makes me wonder what else lurks in the html spec. How come we don't all know about and use this all the time? ( we will now!! )
# Posted By Michael Evangelista | 4/21/08 1:03 PM
I can't believe this is the first I am hearing about this! Makes me think of all the other cool things about html that have been snuck in without anyone telling me!

Thanks Rob!
# Posted By Gary Gilbert | 4/21/08 2:58 PM
@Will, CSS support would indeed be nice. I thought about using jQuery to add the onError attribute after load, but I'm sure they won't apply once they loaded, so we would have to loop over them and check the completed status like Todd & Ray mentioned about doing with Spry.... Like I said, I wrote a similar script and it works, but it's sooo much simpler to write it straight up in the markup.

@Ray, I don't mind it at all ... we usually use your blog for such threads, so it's nice to use mine for once :)
# Posted By Rob Gonda | 4/21/08 3:09 PM
Hmm, am I not right in thinking this is only useful for people with javascript?

http://www.w3schools.com/jsref/jsref_onError.asp
# Posted By Luke | 4/28/08 5:58 AM
@Luke, you're totally correct. This will only work for people with JavaScript enabled (I posted the same link in an earlier comment).
# Posted By Rob Gonda | 4/29/08 9:00 AM
BlogCFC was created by Raymond Camden. This blog is running version 5.1.004.