Firefox3でFlashにwmode属性を追加して透明な画像をマスクする
Windows環境のFirefox3でFlashの上にレイヤーとしてimgをかぶせたいときに参考になるであろうエントリー。
以前、はてな市民にもなったことだし、群衆の叡智を使ってみる このエントリーではてなーに疑問をぶつけてみたんだけどまったく反応がなくてそのまま放置されていた問題に再び挑戦してみたところ解決した!
どんな問題かおさらい
http://www.radio-i.co.jp/ このページの このFlashの上にimgを貼り付けてリンクさせ、ポップアップのページを新しいタブに開きたい。
以前のエントリーはimgをenbedよりも前に挿入してposition:absoluteにしても、imgがFlashの下側に潜ってしまってクリックできない。という状況であった。
問題を解決できたソース
var link = document.createElement('a'); link.target = "_blank"; link.href ='http://www.radio-i.co.jp/NOAView/cgi-bin/NOAData.Now?id=0469'; var img = document.createElement('img'); img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABnRSTlMA%2FwD%2FAP83WBt9AAAADElEQVR4nGP4%2F%2F8%2FAAX%2BAv4N70a4AAAAAElFTkSuQmCC'; img.style.cssText="position:absolute; width:297px; height:95px;" link.appendChild(img); var p = document.evaluate('id("nowPlayTop")//embed', document, null, 7, null); p.snapshotItem(0).setAttribute('wmode','transparent'); //マスクをembedよりも前の位置に挿入。またこの処理によりwmodeが適用される。 p.snapshotItem(0).parentNode.parentNode.insertBefore(link, p.snapshotItem(0).parentNode.parentNode.firstChild);
ソース解説
マスク(レイヤーもどき)作成
重要な処理は以下の2つ
- embedタグよりも前の位置にマスクとなるimgを挿入する。
- wmodeを適用させるにはsetAttributeしただけでは足りない。insertBeforeなどでレンダリング(?)し直すとwmode適用される。詳しくは→wmodeを動的に設定する方法
これ以降はwmode適用条件を知らないときに書いたので参考にならない。embedの仕様の適当さがうかがえるだけ。
処理の順番を変えて失敗の例
//DOMを変えてからwmodeを設定しても効果なしの例 var link = document.createElement('a'); link.target = "_blank"; link.href ='http://www.radio-i.co.jp/NOAView/cgi-bin/NOAData.Now?id=0469'; var img = document.createElement('img'); img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABnRSTlMA%2FwD%2FAP83WBt9AAAADElEQVR4nGP4%2F%2F8%2FAAX%2BAv4N70a4AAAAAElFTkSuQmCC'; img.style.cssText="position:absolute; width:297px; height:95px;" link.appendChild(img); var p = document.evaluate('id("nowPlayTop")//embed', document, null, 7, null); p.snapshotItem(0).parentNode.parentNode.replaceChild(p.snapshotItem(0), p.snapshotItem(0).parentNode); p.snapshotItem(0).setAttribute('wmode','transparent'); p.snapshotItem(0).parentNode.insertBefore(link, p.snapshotItem(0).parentNode.firstChild);
Firebugでembedにwmode属性が追加されたのを確認しても、見かけだけで、うまく適用されていない。
Firefox2では異なる挙動
Firefox 2.0.0.18 で試したところ、以下のコードで出来た。前半のレイヤー作成は同じで、後半の処理を変えている。
var link = document.createElement('a'); link.target = "_blank"; link.href ='http://www.radio-i.co.jp/NOAView/cgi-bin/NOAData.Now?id=0469'; var img = document.createElement('img'); img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAABnRSTlMA%2FwD%2FAP83WBt9AAAADElEQVR4nGP4%2F%2F8%2FAAX%2BAv4N70a4AAAAAElFTkSuQmCC'; img.style.cssText="position:absolute; width:297px; height:95px;" link.appendChild(img); var p = document.evaluate('id("nowPlayTop")//embed', document, null, 7, null); p.snapshotItem(0).parentNode.insertBefore(link, p.snapshotItem(0).parentNode.firstChild); p.snapshotItem(0).setAttribute('wmode','transparent');
embedタグにwmode:transparentを設定するだけでいけた。objectタグの除去や処理の順番は関係なかった。Firefox2のほうが正しい動作をしている(と思う)。