flash插入頁面後在IE下stageWidth為0的bug
用SWFObject,將swf檔案嵌入網頁後,在IE瀏覽器中首次瀏覽正常,重新整理後,stageWidth就為0了,swf中基於stageWidth定位的元素,就會錯亂。
轉自(ljhzzyx 2009-09-24 14:44:20)
首先區分一下stage的stageWidth和width屬性。stage.stageWidth是flash player的寬度,stage.width是指stage裡content的寬度,如果這個舞臺(stage)裡什麼內容都沒有,stage.width就是0。
現在的需求是在執行期獲得舞臺的高寬,以期編碼實現將元件新增到舞臺中央等這樣的效果。但是我得到的stageWidth 和 stageHeight 都為0。
Turns out that when the stage is initialized, it's stageWidth and stageHeight properties are 0 until a Stage RESIZE event is triggered. This event is dispatched when the scaleMode property of the Stage object is set to StageScaleMode.NO_SCALE and the SWF file is resized ie. when the stage is rendered by the Flash Player. So if you need to add a display object onto the stage and its positioning is dependent on the stageWidth or stageHeight properties at runtime, it’s best handled by a listener that is subscribed to the Stage RESIZE event.
在IE中SWF檔案的stageWidth 和 stageHeight 被初始化為0,再延遲一段時間後會更新成正確的數值。在SWF檔案更新stageWidth 和 stageHeight屬性時,會觸發stage物件的resize事件。因此, 可以給stage新增resize事件處理器,將取得stageWidth 和 stageHeight值及後續工作放在resize處理函式裡做,一旦stageWidth 和 stageHeight值大於0,則將此resize監聽器取消掉。
Interestingly, despite universal claim that the Flash Player behaves exactly the same on all browsers, this problem only appears in a couple of browser/plugin configurations, namely FireFox/OSX and IE/Win. And strangely, on Safari and Firefox/Win, the RESIZE event is not even dispatched on page load, and neither does the Flash Player register the stageWidth and stageHeight properties as being 0. I have not tested the problem on other platforms but you are certainly welcome to do so yourselves and report your observations in the comments section.
一般認為,flash檔案在不同瀏覽器中的行為是一致的。如上所述,在FireFox/OSX 和 IE/Win這種搭配才有這樣的bug。
SWFObject.js裡的解決方案
在swfobject.js裡找到函式function createSWF(attObj, parObj, id)裡面針對winIE的處理方法是:
el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
看了一下Adobe自己的AC_OETags.js,他是用document.write方法直接寫入,沒有這個問題;
直接寫靜態html(object)沒有這種問題;
直接訪問這個flash的地址,也沒有這種問題。
SWFObject在IE下的BUG
如果Flash裡繪製的物件的寬高是自適應Flash的寬高的,那麼,使用SWFObject來插入Flash在IE會導致一個問題,當這個Flash被快取後,也就是第二次訪問該頁面時,在該Swf檔案被載入時,獲取到的stage.stageWidth和stage.stageHeight為0,繪製的物件也就看不到了。
在Flash裡監聽resize事件,找出解決方法
用IE的話,會看到5行,有兩次resize事件,這也就導致了Flash在載入的時候繪製物件錯誤(寬和高為0):
數字是stage.stageWidth和stage.stageHeight
info
resize
0 x 0
resize
300 x 300
如果用Firefox等瀏覽器,只輸出兩行文字,沒有resize事件:
info
300 x 300
AS裡的解決方案
通過監聽resize事件,當stage.stageWidth和stage.stageHeight大於0時再進行初始化
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextField;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
public class AutoSizeExample extends Sprite
{
private var txt:TextField;
public function AutoSizeExample()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
txt = new TextField();
txt.multiline = true;
txt.wordWrap = true;
txt.text = "info/n";
addChild(txt);
if (stage.stageWidth>0 && stage.stageHeight>0){
createChild();
}else{
stage.addEventListener(Event.RESIZE,onResize);
}
}
private function onResize(e:Event):void
{
if (stage.stageWidth>0 && stage.stageHeight>0){
stage.removeEventListener(Event.RESIZE,onResize); //刪除事件監聽
createChild();
}
//否則繼續監聽事件,直到stage.stageWidth和stage.stageHeight大於0時才初始化
}
private function createChild():void
{
//進行初始化操作,建立各物件
//.......................
var w:Number = stage.stageWidth;
var h:Number = stage.stageHeight;
txt.appendText(w + " x " + h + "/n");
}
}
}