Bug 9582 - img.onload event ONLY fires when .src changes
Summary: img.onload event ONLY fires when .src changes
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 417.x
Hardware: Mac OS X 10.4
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
: 15499 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-06-25 13:37 PDT by Jeffrey Schrab
Modified: 2022-07-06 14:45 PDT (History)
8 users (show)

See Also:


Attachments
test case (986 bytes, application/xhtml+xml)
2006-06-26 02:10 PDT, Alexey Proskuryakov
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jeffrey Schrab 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.
Comment 1 Alexey Proskuryakov 2006-06-26 02:10:39 PDT
Created attachment 9042 [details]
test case

Same test, as an attachment.
Comment 2 mitz 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.
Comment 3 David Carson 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.


Comment 4 Jeffrey Schrab 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'?"
Comment 5 David Kilzer (:ddkilzer) 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?

Comment 6 Mark Rowe (bdash) 2007-10-14 06:21:18 PDT
*** Bug 15499 has been marked as a duplicate of this bug. ***
Comment 7 Christopher Schmidt 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.)
Comment 8 Eric Seidel (no email) 2007-10-14 10:47:00 PDT
This is kinda related to bug 15484.
Comment 9 Hyongyoub Kim 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.
Comment 10 Radar WebKit Bug Importer 2022-07-06 14:45:52 PDT
<rdar://problem/96549817>