Image onLoad Event + JavaScript Issue with Internet Explorer

By  on  

I was recently coding an application that would inject an image into the page and then execute a given function when the image's onLoad event fires. My code was working everywhere except Internet Explorer. That wasn't all together shocking initially but the fact that even IE8 was failing to the fire the onLoad event was discouraging. Here's what my code looked like:

var img = new Element('img',{
	alt: this.title ? this.title.get('html') : this.options.url,
	src: this.options.url,
	events: {
		error: function() {
			this.messageBox.set('html',this.options.errorMessage);
			img.dispose();
		}.bind(this),
		load: function() {
			img.setStyle('display','');
			this.unfade();
			if(!this.footer) {
				img.setStyle('cursor','pointer').addEvent('click',this.close.bind(this));
			}
		}.bind(this)
	},
	styles: {
		display: 'none'
	}
}).inject(this.messageBox);

On a hunch I detached the "src" assignment and coded that as a separate statement:

var img = new Element('img',{
	alt: this.title ? this.title.get('html') : this.options.url,
	events: {
		error: function() {
			this.messageBox.set('html',this.options.errorMessage);
			img.dispose();
		}.bind(this),
		load: function() {
			img.setStyle('display','');
			this.unfade();
			if(!this.footer) {
				img.setStyle('cursor','pointer').addEvent('click',this.close.bind(this));
			}
		}.bind(this)
	},
	styles: {
		display: 'none'
	}
});
img.set('src',this.options.url).inject(this.messageBox); //for ie

Not too surprisingly that worked. The reason my modification worked is that image was being pulled from cache as soon as the SRC attribute was set, thus "beating" the event assignment to the punch. Keep this in mind if you run into onLoad issues with your images.

Recent Features

  • By
    I’m an Impostor

    This is the hardest thing I've ever had to write, much less admit to myself.  I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life.  All of those feelings were very...

  • By
    Send Text Messages with PHP

    Kids these days, I tell ya.  All they care about is the technology.  The video games.  The bottled water.  Oh, and the texting, always the texting.  Back in my day, all we had was...OK, I had all of these things too.  But I still don't get...

Incredible Demos

  • By
    Telephone Link Protocol

    We've always been able to create links with protocols other than the usual HTTP, like mailto, skype, irc ,and more;  they're an excellent convenience to visitors.  With mobile phone browsers having become infinitely more usable, we can now extend that convenience to phone numbers: The tel...

  • By
    Detect Vendor Prefix with JavaScript

    Regardless of our position on vendor prefixes, we have to live with them and occasionally use them to make things work.  These prefixes can be used in two formats:  the CSS format (-moz-, as in -moz-element) and the JS format (navigator.mozApps).  The awesome X-Tag project has...

Discussion

  1. I ran into that issue a couple years ago when I made an image viewer script like Lightbox. It was very annoying and hard to pin down, but eventually figured out I needed to make sure the src attribute was the last thing I assigned to the new image.

  2. Great pick up! I ran into this issue (not knowing until now) just last week, I moved on to another project but I am now going to go back and revisit that code.

    Thanks!

  3. @Kendall: Yep, I’m upgrading a lightbox.

  4. For this example it would add more code, but you can check if a img element has been loaded by its “complete” attribute.

    if(img.complete) imgLoaded();
    else img.addEvent('load', imgLoaded);
    
  5. IE is plain crazy sometimes… ok, ALL the time!

  6. Richard

    Brilliant work, I had the same issue some time ago.

  7. Adardesign

    I had the same issue lately, I added a dynamic parameter to the image src like
    path/to/img.jpg+ "?" + new Date().getTime();

    This makes sure it doesn’t take the image from cache since it has a new parameter value each time.

    Your solution solves the problem with a much clearer and more efficient way.

    Thank

  8. @Adardesign: That’s not a terrible solution but you’re preventing caching instead of modifying your code. Not a good trade off.

  9. alec

    There is nothing IE-related or even remotely surprising about this. You need to be aware of the fact that JS can be multi-threaded, and that all requests for external resources are asynchronous (non-blocking). By setting the src property you are in effect spawning a new thread to go get that image, and attempting to set handlers or write inline code around a thread that is already running is just asking for trouble.

    You wouldn’t try to set event handlers on an XmlHttpRequest after calling send() would you? The principal is exactly the same.

  10. Just ran across this. Thanks for the solution.

  11. viaria

    good solution thanks, just for you to know the corner copy button of second black box is not working. chrome win7

  12. mike

    I am trying to do the same thing with multiple images and running into problems.

    I have bunch of images that I am trying to set images as this:

    var myImage1 = new Image().bind.this(), 
    .load(function () { 
    
    });
    myImage1.src= teamA.png
    

    can sobody look at this and let me know what I am doing wrong

  13. Brilliant… I am always forgetting about that lame ie thing pulling images from cache so quickly.

    Thanks for posting!

  14. Sjoerd

    Thanks David! Your post just saved me from hours of IE pain.

  15. Theo Hendy

    Thanks a lot for this post! Didn’t think it would be this easy.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!