If you develop and push to production, you most likely have experienced broken images on your dev instance. You may have also run into broken images on production due to user/admin error, etc. Wouldn’t it be nice if you could display a default placeholder image without having to take a hit on your file system, checking to see if it exists, before your load each image?
Thanks to Ryan Stille’s recent blog post, I have been made aware of a (not so great) solution. Apparently the img tag, along with others such as object, script and style have error events. We can listen for the error event and load a placeholder image in place of the default browser error image.
The catch is the event handler must be attached before the browser fires the error event. Also, the error event may not be correctly fired when the page is served locally. The error event relies on HTTP status codes and will generally not be triggered if the URL uses the “file:” protocol.
In simpler terms, the only solution I’ve found is to either place the event handler inline with the img tag, assign the img src via JavaScript or recursively search each image’s complete state or naturalWidth once the window is done loading. I’ve tried using “$().on()” and “$(“img”).error()” both after the document loads and inline before the element is loaded. However neither solution works, which doesn’t make much sense to me.
I am including multiple examples because this is not a one-solution-fits-all scenario.
The first working example displays a placeholder image using the inline method if the error event is thrown. Notice the onerror handler is reset when it’s run so you don’t run into an infinite loop if your placeholder image also fails.
<img src="images/myImage.jpg" alt="My Image" onerror="imageError(this)">
<script>
function imageError(element) {
element.onerror='';
element.src='/images/imgPlaceholder.png';
}
</script>
The second working example, also using the inline method, will call a script that will report the broken image and load the placeholder. The script returns an image with the proper image MIME type.
<img src="images/myImage.jpg" alt="My Image" onerror="imageError(this)">
<script>
function imageError(element) {
element.onerror='';
element.src='logBrokenImage.cfm?image=' + element.src';
}
</script>
The third working example uses JavaScript to load the image and displays a placeholder if that image fails to load.
<img id="myImage">
<script>
$('img').one( 'error', function() {
$(this).attr( 'src', '/images/imgPlaceholder.png' );
});
$('#myImage').attr( 'src', 'myImage.jpg' );
</script>
The final working example recursively searches through each image after the window loads. If it finds the state incomplete or the natural width of the image is 0, then it loads the placeholder image.
<img src="images/myImage.jpg" alt="My Image">
<script>
$(window).load(function() {
$('img').each(function() {
if ( !this.complete || ( !$.browser.msie && ( typeof this.naturalWidth == "undefined" || this.naturalWidth == 0 ) ) ) {
this.src = '/images/imgPlaceholder.png';
}
});
});
</script>
#error, #event, #handler, #img, #javascript, #jquery, #src