Consider the following example: ------------------------------------------ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <script type="text/javascript"> function dothis() { document.getElementById('demoImage').onload = function() { alert('done'); } document.getElementById('demoImage').src = "http://images.apple.com/main/elements/homeiconus.gif"; } function dothat() { document.getElementById('demoImage').onload = function() { alert('done'); } document.getElementById('demoImage').src = "http://images.apple.com/main/elements/homeiconus.gif"; } </script> </head> <body> <a href="#" onclick="dothis();">dothis</a> | <a href="#" onclick="dothat();">dothat</a><br /> <img src="http://images.apple.com/main/elements/homeiconus.gif" id="demoImage" alt="" /> </body> </html> ------------------------------------------ It would appear that onload events for img elements (possibly more) only will fire when there is an actual change to the .src in the above example. The "alert()'s" in the onload functions never fire because the value of src changes. This is not how other major browsers (IE 6.0 and Firefox 1.5 tested) behave - onload events always fire after they are complete, even if they don't do a whole lot in the case of unchanged content. There is a work around but it's not nice: ------------------------------------------ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <script type="text/javascript"> function dothis() { document.getElementById('demoImage').onload = function() { alert('done'); } document.getElementById('demoImage').src = "http://images.apple.com/main/elements/homeiconus.gif?random="+Math.random(); } function dothat() { document.getElementById('demoImage').onload = function() { alert('done'); } document.getElementById('demoImage').src = "http://images.apple.com/main/elements/homeiconus.gif?random="+Math.random(); } </script> </head> <body> <a href="#" onclick="dothis();">dothis</a> | <a href="#" onclick="dothat();">dothat</a><br /> <img src="http://images.apple.com/main/elements/homeiconus.gif" id="demoImage" alt="" /> </body> </html> ------------------------------------------ With differing URL's, the src is different so onload events will fire off. But this is a waste - the browser goes off the server for images that it really doesn't need, just so events will fire off.
Created attachment 9042 [details] test case Same test, as an attachment.
IIRC, the DOM specification doesn't include load events for IMG elements, so I think whether the current behavior is a bug or not is mostly a question of what Firefox and IE (plan to) do. At least, the behavior of SCRIPT and other load events should be considered at the same time.
I wonder if the onLoad event should fire when (a) the first block of data arrives, or (b) when the full response has arrived or (c) when the image has been converted to a platform bitmap or (d) when it has been rendered. Comment #0 says that it fires when it is complete - but what is complete? If the image is not visible, then it may not be loaded. If the image is hidden, then it may not be fully converted to a bitmap, maybe just the height and width is available at this point. Need to do some testing with IE and FF.
I would like to make motion that it should be "(d) when it has been rendered." While it may seem selfish for me to say so, my real-world need that lead to the discovery of this bug/quirk was in an effort to implement some DHTML cross-fade effects. I wanted to make sure that my opacity=0 image was loaded before my transition began. It would seem to me that the usefulness of .onload, particularly for images, is to be notified that an image is ready-to-go. And ready-to-go, I would say, means rendered. Of course my case here is for a transparent image (via opacity style) or otherwise not visible image may lead to a fine point of "what do you mean by 'rendered'?"
(In reply to comment #3) > I wonder if the onLoad event should fire when > (a) the first block of data arrives, or > (b) when the full response has arrived or > (c) when the image has been converted to a platform bitmap or > (d) when it has been rendered. What do other browsers do? Can we tell what MSIE and Firefox do?
*** Bug 15499 has been marked as a duplicate of this bug. ***
My experience with FF + IE has always been 'at the time onload is called, swapping the image from display:none to display:block results in a fully rendered image being displayed. That probably only makes it clear that it's not 'a', described below, since anything else could happen within a repaint, and there's no way to tell the difference visually. The current behavior in Safari seems to be matched by Opera. This was reported as part of the OpenLayers project: http://trac.openlayers.org/ticket/758 (I would love to see this fixed, as, at the moment, OpenLayers is relatively unusable under Safari for many users.)
This is kinda related to bug 15484.
I know this issue has seen no action for 9 years. Here is a ping that this issue does matter in the real world. Many sites use this "load the same source twice + onload event" technique to load images asynchronously and then display them when they are already in the memory cache. Looks like Chromium fixed this last year. https://codereview.chromium.org/1047563002 The second load event does not fire because the following check in ImageLoader. http://trac.webkit.org/browser/trunk/Source/WebCore/loader/ImageLoader.cpp#L217 Tried simply pretending the images are always different. It seems to work okay, but not sure about any side effects this would have on CachedImage::didAddClient and CachedImage::didRemoveClient.
<rdar://problem/96549817>