IE6でpng画像にロールオーバーする方法

Javascript

IE6でpng画像にロールオーバーする時に動かなかったので、そのときに調べたことのメモ。
JSの記述を書き換えれば動くようになりました。

IE6でpngを使うとき

私はIE6でpngを使うときはDD_belatedPNGを使っています。

これはJSを読み込んであとは<head>の中などに以下を記述すればいいだけなので、とても簡単に実装できます。

<script type="text/javascript">
    DD_belatedPNG.fix('img, .png_bg');
</script>

しかしこれと合わせて次のJSを使いpngをロールオーバーしようとするときにIE6で困ったことになります。

画像のロールオーバー

そして、画像のロールオーバーするときに使っているJSが以下になります。

function smartRollover() {
  	if(document.getElementsByTagName) {
	  		var images = document.getElementsByTagName("img");
			for(var i=0; i < images.length; i++) {
			if(images[i].getAttribute("src").match("_off.")){
					images[i].onmouseover = function() {
						this.setAttribute("src", this.getAttribute("src").replace("_off.", "_on."));
					}
					images[i].onmouseout = function() {
						this.setAttribute("src", this.getAttribute("src").replace("_on.", "_off."));
				}
			}  		
		}  	
	}
}

if(window.addEventListener) {
	window.addEventListener("load", smartRollover, false);
}
else if(window.attachEvent) {
  	window.attachEvent("onload", smartRollover); 
}

画像名の最後(拡張子の前)が_offの画像をオンマウスすると_onの画像に切り替わるというものです。

問題点

この2つを使ってpngの画像をロールオーバーしようとしてもIE6では動きません。何度試しても動かなかったので、相性がわるいのかなと思ってましたが 原因はこれでした。

<img>要素を非表示にして、VMLの要素を前に挿入することで、今まで<img>があったところにVMLを使って画像が表示されるようになります。普通の<img>要素の描画ではPNGを透過させられないのに対し、VMLの描画では透過させられるということを利用しているわけですね。見つけた人はすごい!

ここで、JSが動かない理由がわかってきたでしょうか。<img>要素に対してイベントハンドラを設定しても、<img>要素は非表示になっており、見えているのはVMLで表示されている画像なのです。これでは<img>要素に設定したイベントハンドラは動作しませんね。

解決方法

というわけで、さきほどの問題点が書いてあるサイトにも書いてありますが、解決するには以下のコードを書き換えれば書けばOKです。

<script type="text/javascript">
    DD_belatedPNG.fix('img, .png_bg');
</script>

以下のものに修正

<script type="text/javascript">
    var oldFixPng = DD_belatedPNG.fixPng;
    DD_belatedPNG.fixPng = function (el) {
        oldFixPng(el);
        if (el.vml && el.vml.image.fill.getAttribute("src").match(/_off\./)) {
            el.vml.image.shape.attachEvent('onmouseenter', function() {
                var image = el.vml.image.fill;
                image.setAttribute("src", image.getAttribute("src").replace("_off.", "_on."));
            });
            el.vml.image.shape.attachEvent('onmouseleave', function() {
                var image = el.vml.image.fill;
                image.setAttribute("src", image.getAttribute("src").replace("_on.", "_off."));
            });
        }
    };
    DD_belatedPNG.fix('img, .png_bg');
</script>

参考サイト