NEW 9582
img.onload event ONLY fires when .src changes
https://bugs.webkit.org/show_bug.cgi?id=9582
Summary img.onload event ONLY fires when .src changes
Jeffrey Schrab
Reported 2006-06-25 13:37:53 PDT
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.
Attachments
test case (986 bytes, application/xhtml+xml)
2006-06-26 02:10 PDT, Alexey Proskuryakov
no flags
Alexey Proskuryakov
Comment 1 2006-06-26 02:10:39 PDT
Created attachment 9042 [details] test case Same test, as an attachment.
mitz
Comment 2 2006-06-26 02:29:45 PDT
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.
David Carson
Comment 3 2006-07-03 19:46:23 PDT
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.
Jeffrey Schrab
Comment 4 2006-07-04 09:48:06 PDT
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'?"
David Kilzer (:ddkilzer)
Comment 5 2006-07-04 15:37:09 PDT
(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?
Mark Rowe (bdash)
Comment 6 2007-10-14 06:21:18 PDT
*** Bug 15499 has been marked as a duplicate of this bug. ***
Christopher Schmidt
Comment 7 2007-10-14 06:37:42 PDT
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.)
Eric Seidel (no email)
Comment 8 2007-10-14 10:47:00 PDT
This is kinda related to bug 15484.
Hyongyoub Kim
Comment 9 2016-04-28 20:36:31 PDT
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.
Radar WebKit Bug Importer
Comment 10 2022-07-06 14:45:52 PDT
Ahmad Saleem
Comment 11 2024-05-21 03:49:26 PDT
I took test cases from Blink commit and it seems that WebKit ToT (279051@main) passes them now. Blink Commit - https://github.com/chromium/chromium/commit/3a2965e93805f4cf213b8c1f84ed8141145f951b It would be good to import these tests IMO.
Note You need to log in before you can comment on or make changes to this bug.