Baffling IE Behavior with PNG Opacity Fix
This has been baffling me to no end for the past few days. I’ve exhausted my own skill to figure the problem out, so I’m putting it up here in the hopes that someone more knowledgeable than I can solve the puzzle.
The other day I was browsing message board posts and someone was asking for information on how to get Internet Explorer to play nice with variable opacity PNG images. I suggested that she try Andrew Gregory’s Improved PNG Behavior file for IE which the poster did. However, she reported the most unusual thing: when implemented on her page, all of her images vanished from view!
Puzzled, I made my own (very ugly) test pages for three different versions of the behavior file. Surprisingly, when I tested Andrew’s behavior file the PNG image on my page vanished too! So I dove into the the code and traced the problem down to line 54 of his file, which reads: element.runtimeStyle.filter = ''; // remove filter.
Commenting that line out solved the disappearing image problem, but it seemed like a messy hack more than a fix. I had to assume he put the line in there for a reason. So I decided to litter the functions in the file with alert()’s to help me visualize the problem. Then I noticed the most bizarre thing. Inside the fixImage() function, both the if block and the else block were executing procedurally. That is, first the statements in the if block executed and applied the appropriate IE filter to the PNG image, but then the else block was executing right afterwards and was removing the filter even though the if block had evaluated to a boolean true!
Here is the relevant code I was working with (some comments, and the alert()s added by me):
function fixImage() {
// check for real change
if (realSrc && (element.src == realSrc) && IS_PNG.test(element.src)) {
element.src = blankSrc;
alert("element.src set to " + blankSrc); // help debug
} else {
if (element.src != blankSrc) {
// backup old src
realSrc = element.src;
}
// test for png
if (realSrc && IS_PNG.test(realSrc)) {
alert("fixImage() 'test for png' IF statement executing"); // help debug
element.src = blankSrc;
element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + realSrc + "',sizingMethod='scale')";
} else {
/*
?? It apparently causes any fix[ed]Image() to disappear! Not sure why it even executes,
?? because the if block above executes too...and doesn't that mean that the else
?? statement should not execute?!?!
*/
alert("Inside fixImage() 'test for png' else statement: removing filter..."); // help debug
element.runtimeStyle.filter = ''; // remove filter
}
}
}
So now I’m really puzzled. What’s going on? I emailed Andrew on the matter and he said that he couldn’t replicate this behavior. I am testing this in the latest Internet Explorer 6 on Windows XP Home with Service Pack 2 installed. (Or, to be completely anally retentive, version 6.0.2900.2180.xpsp_sp2_rtm.040803-2158 as reported by Help → About Internet Explorer.) He was using the latest IE 6 on Windows 2000, however, so maybe the two versions are different somehow.
All the code is in my PNG test directory and the relevant page is the improved_pngtest.html document. The .htc file is called from within that document. If anyone out there is bored or wants to try figuring out what’s happening in IE, I’d be very interested to hear about your findings.
I should also point out that Andrew has updated and re-written some parts of this function his new file works without any problems even on my configuration. I’d still like to figure out why IE is executing else statements after their respective if blocks have executed though.
if the size of the image is not set, IE resizes the image to the size of blank.gif
tom stovall
5 Jul 05 at 2:55 PM