Problem with changing img src in Chrome

I am having trouble with changing the src of an image in Chrome (other Webkit based browsers seem to be okay).

In the javascript I am pre-loading the new image, and then changing the src of the existing image to that of the new image. But Chrome doesn’t actually update the display until the onload function of the new image has completed (it seems).

The problem with this is that it means you can’t run any code that relies on the image’s src having been updated (e.g. getting the offsetWidth of the new image).

This example shows the problem: http://www.iliveinabin.com/Chrome-ad-blocker-test/ (links when clicked should change the image to a 500px transparent GIF and then alert “image should now be switched”).

I found that setting the image src to a blank string before changing to the new image’s src fixes the problem in Chrome when the AdBlock plugin is disabled. Using setTimeout to trigger the code following the src being changed seems to work when the AdBlock plugin is enabled as well.

Anyone else come across this or have any info?

The code for the test page is:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Chrome Ad blocker test</title>
</head>
<body>
<img src="./01.png" alt="Pogs > Icee 01.png">
<p><a href="#" onclick="return s(false)">Switch Image normally</a></p>
<p><a href="#" onclick="return s(0)">Switch Image setting src to blank string first</a></p>
<p><a href="#" onclick="return s(true)">Switch Image with timeout</a></p>
<script type="text/javascript">function s(t){
	var k = document.getElementsByTagName('img')[0];
	var j = new Image();

	j.onload = function(){
		k.oldsrc = k.src;
		if(t === 0){k.src = "";}
		k.src = j.src;
		t ? setTimeout(alert, 1, "image should now be switched") : alert("image should now be switched");
	}
	j.src = k.oldsrc ? k.oldsrc : "./blank.gif";
	return false;
}</script></body>
</html>

It just means that you need to start firing all your logic on theonload event as well. I don’t see where the problem is…

Sorry, I don’t understand your comment? The logic (alerting “image should now be switched”, but in real life it might be getting the offsetWidth of the image) is in the onload event, and this is where it doesn’t work. If you execute this logic outside of the onload event by using setTimeout it then works.

What logic that should be inside the onload event are you referring to?

Here is an example that could help you wrap your head around the problem. You can replace the images I use with those of your choosing…:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<html>
<head>
<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8”>
<title>Chrome Ad blocker test</title>
</head>
<body>
<img src=“Lighthouse.jpg” alt=“Pogs > Icee 01.png”>
<p><a href=“#” onclick=“return s(false, ‘Koala.jpg’)”>Switch Image normally</a></p>
<script type=“text/javascript”>function s(t, image){
var k = document.getElementsByTagName(‘img’)[0];
var j = new Image();

j.onload = function(){
    if(typeof k.oldsrc == 'undefined') {
	k.oldsrc = j.src;
	}
	else {
	k.oldsrc = k.src;
	}
    k.src = j.src;
    alert("image should now be switched");
}

k.src == k.oldsrc ? j.src = "Jellyfish.jpg" : j.src = image;
return false;

}</script></body>
</html>

Thanks for the example code, but when I tried it I still get the same result as before - the image is not switched at the point the alert is triggered, only once you click okay on the alert and the onload function finishes.

I’ve uploaded an example using your code here: http://www.iliveinabin.com/Chrome-ad-blocker-test/2.html

When you click the link it should change to the 500px GIF and alert the size of the new image (500px). But it doesn’t actually change the image until after the onload function has finished.