Home > JavaScript
JavaScript Archive
SWFObjectのDynamic Publishingを使うとIEとかでStage.stageWidthとheightが一瞬ゼロになるという都市伝説は実在した!
- 2009-05-19 (火)
- ActionScript | JavaScript | flash
IEとかでstage基準の中央寄せができなくなることがある
特定の状況で一定時間、swfの「stageのwidthとheightがゼロ」になり、stageの中心にモノを置いたはずなのに、変な位置にきてしまうことがあります。今回はその問題を肩パッド探検隊が追います。
基本的な対処法は以下のblogにおまかせ!
崖っぷちWEBデザイナーブログ | stage幅取得のタイミングをテストしてみた
二番煎じですが、ちょこっと書いていきます。対処するクラスが見たい方はページ内リンクで!
SWFObject1.5、SWFObject2.1のDynamic PublishingでWinIEがダメで、MacのFirefoxも怪しいらしい。あとMacのFla:verで作ったスクリーンセーバーもダメ
SWFObjectのDynamic Publishingの場合
SWFObjectで空divを起点に動的にObjectタグを埋め込むやつをすると
- IE全般
- MacのFireFox
で、一瞬だけstage.stageWidthとstage.stageHeightが0になります。
Dynamic Publishingってのは以下のjsコードで空divに埋め込むやつです
//SWFObject1.5
var so = new SWFObject("hoge.swf", "topFlash", "100%", "100%", "8", "#FFFFFF");
so.write("flashcontent");
//SWFObject2.xならDynamic Publishingと呼ばれるタイプ
swfobject.embedSWF("hoge.swf", "flashcontent", "100%", "100%", "9.0.45", "expressInstall.swf", flashvars, params, attributes);
widthとheightがゼロになるサンプル
サンプルでテストしてみてください。
サンプルのasはこちら
- wmodeはtransparent
- 最初にstageの中心に文字を書こうとしますが、ダメブラウザだと文字が(0,0)にきます
- swfの中心に「うんこ」と書かれたらOKブラウザ!
- 崩れてたらStageの初期サイズが0のダメブラウザ。IEかMacのFirefoxです
- traceされているテキストは以下です
- 一発目にStageのwidthとheightをチェック
- ENTER_FRAMEイベントと何回ENTER_FRAMEが回ったか
- ENTER_FRAMEでStageのwidthとheightをチェック
- stageのResizeイベント
- stageWidthがゼロだったらADDED_TO_STAGEイベントを取得
- それぞれのgetTimer
サンプルの結果
- mac os10.5
-
Firefox3 Opera9.6 Safari3 Safari4 △ ○ ○ ○ - (崖っぷちさんとこではMacのFirefoxでもアウトでしたが私の環境ではOKでした)
ENTER_FRAMEの方がRESIZEイベントよりも速くStageのwidthが変わったことを知る
このサンプルを作っていてわかったのですが、ENTER_FRAMEでwidthとheightを監視して、ゼロじゃなくなったあと(ENTER_FRAMEのイベントハンドリングが終わったあと)にRESIZEイベントが飛んできます。なので、無意味なタイムラグが生じます。
SWFObjectでの原因
SWFObjectの原因は以前のエントリで妄想を膨らませましたが、これは間違っていると思います。詳細ご存知のかた、おしえてください!
fla:verで作ったスクリーンセーバーをMacで再生するとき
fla:ver(http://flaver.jp/)というスクリーンセーバー作成ソフトで作ったスクリーンセーバーでも起こります。
ref) Mac OS X 10.5で MovieClip が表示されないことがあります
対処するクラスを作りました
大変つまらないクラスですがどうかご査収くださいませ
stagesize問題を対処したサンプルの実行結果
対処法について
- Event.RESIZEよりEvent.ENTER_FRAMEの方がstageの幅高の取得が早いので、ENTER_FRAME監視がベター
- dispatchEventしてるのは入口と出口を分けないため。
(newする前にif(stage.stageWidth * stage.stageHeight != 0)を挟めばOKブラウザをスルーできますが、OKブラウザとNGブラウザで出口がバラバラになるとややこしいのでこうしました。)
クラスとサンプル
- StageSizeChecker.as
-
package com.katapad.utils { import flash.display.Stage; import flash.events.Event; import flash.events.EventDispatcher; import flash.utils.getTimer; /** * WinIEやMacFFでSWFObjectのDynamic Publishingをしたときにおこる * Stage.stageWidthとstageHeightが0になる問題を * EnterFrameで監視してチェックするクラス<br /> * Event.RESIZEが飛んでくるタイミングがEvent.ENTER_FRAMEより遅いので、 * EVENT.COMPLETEのついでにstageからEVENT.RESIZEも飛ばします(オプション)。 * * @author katapad.com * @version 0.1 * @since 2009/03/17 3:40 * @usage * <p>MainクラスやPreloaderクラスの最初に</p> * <pre> * var StageSizeChecker:StageSizeChecker = new StageSizeChecker(stage); * StageSizeChecker.addEventListener(Event.COMPLETE, delayInit); * StageSizeChecker.start(); * </pre> * <p>を書いて、あとはEvent.COMPLETEの受取先で</p> * <pre>event.target.removeEventListener(Event.COMPLETE, delayInit);</pre> * <p>すればOK</p> */ public class StageSizeChecker extends EventDispatcher { /** * stage.stageWidthとstage.stageHeightが0以外になったら配信します。 * @eventType flash.events.Event.COMPLETE */ [Event(name = "complete", type = "flash.events.Event")] //---------------------------------- // static var/const //---------------------------------- //---------------------------------- // instance var //---------------------------------- private var _stage:Stage; private var _isResizeEvent:Boolean; /** * ステージサイズを見張り、ゼロ以外ならEvent.COMPLETEを配信します。 * @param stage * @param isResizeEvent _stage.dispatchEvent(new Event(Event.RESIZE))も同時に発動させるかどうか */ public function StageSizeChecker(stage:Stage, isResizeEvent:Boolean = true) { init(stage, isResizeEvent); } private function init(stage:Stage, isResizeEvent):void { _stage = stage; _isResizeEvent = isResizeEvent; } //-------------------------------------------------------------------------- // // PUBLIC // //-------------------------------------------------------------------------- public function start():void { if (isValidSize()) { complete(); return; } _stage.addEventListener(Event.ENTER_FRAME, check); } //-------------------------------------------------------------------------- // // PROTECTED // //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // // EVENT HANDLER // //-------------------------------------------------------------------------- private function check(event:Event):void { if (isValidSize()) complete(); } //-------------------------------------------------------------------------- // // PRIVATE // //-------------------------------------------------------------------------- private function isValidSize():Boolean { //trace( getTimer(), "_stage.stageWidth : " + _stage.stageWidth ); return _stage.stageWidth * _stage.stageHeight != 0; } private function complete():void { _stage.removeEventListener(Event.ENTER_FRAME, check); if (_isResizeEvent) _stage.dispatchEvent(new Event(Event.RESIZE)); dispatchEvent(new Event(Event.COMPLETE)); _stage = null; } //-------------------------------------------------------------------------- // // GETTER/SETTER // //-------------------------------------------------------------------------- } }
- Comments: 0
- Trackbacks: 2
IEでSWFObjectを使うときの一つの注意点
- 2007-05-21 (月)
- JavaScript | flash
2009-05-19追記 対処法をちょこっと書きました http://katapad.com/wp/2009/05/19/stage_size_zero_issue_with_swfobject_on_ie
IEでwidth: 100%、height: 100% のswfを埋め込むときにハマったのでメモ。
IEのムチャクチャな描画速度は、SWFObject を軽く凌ぐようで見事にハマってしまった。リスト化してメモ。
- IEのflash設置速度が速い
- しかし、SWFObjectの処理速度は遅い
- SWFObjectで設定した幅、高さを計算する前に、FLASHの1フレーム目を描画してしまう
- 結果、Stageの幅、高さが0の状態でswfを描画してしまう。
だいたいこのような感じ。IEは描画だけは恐ろしく速い。
解決策は、Flashの1フレーム目に空のフレームをおくことで対処できた。 以前、スーパープログラマに似たような現象を教えて頂いてたのだが、半信半疑だったのでやってなかった。 半信半疑で本当にすみません。額を床につけるほうの土下座をします。
- Comments: 0
- Trackbacks: 0
[JavaScriptとcssを簡単にするためのjQuery] 2ndDay ストライプテーブル
- 2007-02-13 (火)
- JavaScript | css
2日目はストライプテーブルとtrのマウスオーバーイベントを設定する章です。
Table Striping Made Easy
この表組みのように偶数列と奇数列で異なるclassを設定し、背景色を別にします。
ここで覚えることは以下です。
$("table.stripe tr:even").addClass("even");…擬似クラスっぽい:evenを設定$("table.stripe tr").hover(function() { , });…擬似クラス:hoverを設定
$("table.stripe tr:even").addClass("even");
偶数、奇数を設定する擬似クラスっぽいものに:odd, :evenがあります。書き方はcssを編集する感覚でオッケー!!そこにaddClass("even")などを設定することで奇数または偶数の要素にクラスを追加設定できます。
今回のストライプテーブルの設定は以下です。
- ストライプテーブルにするtableにclass stripeを設定します。
$("table.stripe tr:even").addClass("even");- 偶数行 trに以下のcssを設定します。
/ * stripe -----------------------------------*/ table.stripe tr.even td { background-color: #f3f3f3; }
これで偶数行のみ背景色を変更できます。
trのhover時に背景色を変更
trにマウスオーバーしたときにハイライト表示する設定をします
$("table.stripe tr").mouseover(function() {$(this).addClass("hover");})
.mouseout(function() {$(this).removeClass("hover");});
本来なら、jqueryのhoverメソッドを用いればいいのですが、今回のエッセンスはそうではありません。mouseoverとmouseoutの二つのメソッドを同時に指定できるところにあります(たぶん!)。
実際にはマウスオーバーイベントよりhoverの方がよさげなので、僕は以下のように設定しました。
$("table.generalTbl tr").hover(function() {
$(this).addClass("hover");
},
function() {
$(this).removeClass("hover");
} );
メソッドの引数は
hover(hover時の設定,hoverが外れたときの設定)
と、このようになります
- Comments: 0
- Trackbacks: 0
[JavaScriptとcssを簡単にするためのjQuery] 1stDay
- 2007-02-13 (火)
- JavaScript
jQueryをそこそこ使いこなすための日記。チュートリアルがあったので、軽く訳しながら実践してみますね~。
Quicker Than window.onload
DHTMLなど動的なhtmlをいじる際には、window.onloadが必要になってきます。しかし、画像ファイルサイズがでかいときはなかなかロードしてくれない、という問題あります。
「jQuery」にはDOMが読み込まれた時点で、おまじないをかけて(このへん訳できへんかった!)onloadとみなしてユーザ定義関数を実行してくれます。というわけでめっさ速くなる。そのおまじないコードがこれです。
$(document).ready(function(){
// ここにコードを書く!!
});
このように書けばDOM読み込むや否や、さっさと動作してくれます。ということが書いてあったのが1st Day!!
- Comments: 0
- Trackbacks: 0
ホーム > JavaScript
- Search
- Feeds
- Meta
