2007年6月30日 星期六

ActionScript "with" Block Scope 遮蔽效應   [+/-]

Ticore's Blog

ActionScript 有一種 with(obj) {...} 用法
需要對相同物件大量呼叫時,可以節省不少程式碼
不過 with 的使用也會帶來其它的效應
像是遮蔽外層 Scope 變數

ActionScript 2、3 - "with" 遮蔽變數 i:

var i:Number = 1;
trace(i); // 1
with ({i: 2}) {
 trace(i); // 2
}
trace(i); // 1

上述的例子祇有遮蔽一個變數而已
假如把 Object.__resolve 拿進來

ActionScript 2 - "with" & Object.__resolve:

var i:Number = 1;
trace(i); // 1
with ({__resolve: function(){}}) {
 trace(i); // undefined
 trace(_root); // undefined
 trace(_global); // undefined
 trace(_url); // undefined
}

// Ticore's Blog - http://ticore.blogspot.com/

可以發現 with 區塊內所有外層 Scope 變數都會被遮蔽
ActionScript 3.0 也有類似的情況
只是要改用 flash.utils.Proxy

ActionScript 3 - "with" & Proxy Object:

package {
 import flash.display.*;
 public class main extends MovieClip {
  public function main ():*{
   
   with(new ProxyObj()) {
    trace(name);
    // getProperty : name
    // callProperty : trace
   }
   
  }
 }
}

import flash.utils.*;
class ProxyObj extends Proxy {
 
 flash_proxy override function hasProperty(name:*):Boolean{
  return true;
 }
 flash_proxy override function getProperty(name:*):*{
  trace("getProperty : " + name);
  return null;
 }
 flash_proxy override function callProperty(name:*,... rest):*{
  trace("callProperty : " + name);
  return null;
 }
 
}
// Ticore's Blog - http://ticore.blogspot.com/

上面的例子可以看得出來
AS3 with 甚至連 trace 呼叫都可以遮蔽

相關連結:
AS3 利用 with, Proxy 選擇性替換 Scope Variables
AS2 利用 with, Object.__resolve 選擇性替換 Scope Variables
AS3 技巧 - 利用 with 跳過編譯器 Strict Mode 檢查

Read more...

2007年6月29日 星期五

AS3 Number 與 int 預設初始值   [+/-]

Ticore's Blog

又是一個 ActionScript 3.0 神奇之處
原文請參考 quick FYI: Number & int

另外再進一步測試,int 型別參考無法指定為 NaN

var n:Number;
trace(isNaN(n)); // true
var i:int;
trace(isNaN(i)); // false
i = NaN;
trace(isNaN(i)); // false
trace(i); // 0
Read more...

AS2 以 LocalConnection 實作 WeakReference 的方式   [+/-]

Ticore's Blog

這是去年簡報中介紹過的 AS2 實作 Weak Reference 的方式
利用 LocalConnection 可以不用透過參考呼叫
但是又可以被回收的特性來實作

不過由於 Flash Player 9 AS2 LocalConnction 回收有 Bug
使用上需要特別注意
這個程式實驗性遠大於實用性就是了

AS2 WeakReference Class:

/*//

AS2 WeakReference Class, version 0.1.1
(c) 2006 Shih, Wei-Lung
http://ticore.blogspot.com/

AS2 WeakReference Class is freely distributable under the terms of an GNU license.

Events:

onGetReferent
onReleaseReferent
onDispose
onCallback
onObjDead

//*/

import mx.events.EventDispatcher;

class WeakReference {
 
 //---------------------------------------------------------------------------------------------
 
 static var weakRefPrefix:String = "WeakRef";
 static var weakRefIndex:Number = 0;
 
 public var proxyObj:Object;
 public var referentObj:Object;
 public var alive:Boolean = true;
 public var connectionName:String;
 
 private var __lc_caller__:LocalConnection;
 
 //---------------------------------------------------------------------------------------------
 //
 var addEventListener:Function;
 var removeEventListener:Function;
 var dispatchEvent:Function;
 var dispatchQueue:Function;
 //
 //---------------------------------------------------------------------------------------------
 
 public function WeakReference(referent:Object) {
  
  EventDispatcher.initialize(this);
  
  //------------------------------------------------------------------------------------------
  
  this.connectionName = weakRefPrefix + weakRefIndex++;
  
  var weakRef:Object = this;
  
  this.__lc_caller__ = new LocalConnection();
  //this.__lc_caller__.weakRef = this;
  this.__lc_caller__.onStatus = function(infoObj:Object):Void{
   trace(weakRef.connectionName + " LC : " + infoObj.level);
   switch(infoObj.level){
    case "status":
     
     break;
    case "error":
     weakRef.alive = false;
     weakRef.dispatchEvent({type:"onReferentDead", target: weakRef});
     break;
   }
  }
  
  var resolve:Function = function (name):Object {
   if (name == "__name__") {
    return null;
   }
   //trace("name : " + name);   
   //trace("__name__ : " + this.__name__);
   var __name__:String = (this.__name__ == null ? "" : this.__name__ + ".") + name;
   var o:Object = function ():Object {
    //trace("o.__name__ : " + __name__ + "()");
    //callMethod(__name__ + "()");
    weakRef.callMethod(__name__ + "()");
    return __name__ + "()";
   };
   o.toString = function() {
    weakRef.callMethod(__name__);
    return __name__;
   };
   o.__name__ = __name__;
   o.__resolve = resolve;
   _global.ASSetPropFlags(o, null, 7, 0);
   return o;
  };
  this.proxyObj = {};
  this.proxyObj.__resolve = resolve;
  
  
  //------------------------------------------------------------------------------------------
  
  var __lc_callee__:LocalConnection = new LocalConnection();
  referent["__lc_callee__"] = __lc_callee__;
  //_global.ASSetPropFlags(referent, "__lc_callee__", 7, 0);
  
  __lc_callee__["referent"] = referent;
  __lc_callee__.weakRef = this;
  __lc_callee__.connectionName = connectionName;
  __lc_callee__.onStatus = function(infoObj:Object):Void{
   trace(infoObj.level);
  }
  
  __lc_callee__.getReferent = function():Void{
   trace(this.connectionName + " getReferent");
   weakRef.referentObj = this["referent"];
   weakRef.dispatchEvent({type:"onGetReferent", target: weakRef, referent: this["referent"]});
  }
  
  __lc_callee__.dispose = function():Void{
   trace(this.connectionName + " dispose");
   var referent:Object = this["referent"];
   delete this["referent"];
   
   _global.ASSetPropFlags(referent, "__lc_callee__", 0, 7);
   delete referent["__lc_callee__"];
   this.close();
   
   weakRef.dispatchEvent({type:"onDisposed", target: weakRef, referent: referent});
   delete referent;
  }
  
  __lc_callee__.callMethod = function(path:String):Void{
   //trace(this.connectionName + " callMethod()");
   var key:String = "referent";
   var resultObj:Object = WeakReference.evalPath(this["referent"], path);
   weakRef.dispatchEvent({type:"onCallback", target: weakRef, result: resultObj});
  }
  
  __lc_callee__.traceObj = function():Void{
   trace(this.connectionName + " traceObj");
   for(var i:String in this["referent"]){
    trace("referent[" + i + "] : " + this["referent"][i]);
   }
  }
  
  __lc_callee__.connect(connectionName);
  
  delete __lc_callee__;
  delete referent;
  
  //------------------------------------------------------------------------------------------
  
 }
 
 public function getReferent():Void{
  this.__lc_caller__.send(this.connectionName, "getReferent");
 }
 
 public function releaseReferent():Void{
  this.dispatchEvent({type:"onReleaseReferent", target: this, referent: this["referentObj"]});
  this["referentObj"] = null;
 }
 
 public function dispose():Void{
  this.__lc_caller__.send(this.connectionName, "dispose");
 }
 
 public function callMethod(method:String):Void{
  this.__lc_caller__.send(this.connectionName, "callMethod", method);
 }
 
 public function traceObj():Void{
  this.__lc_caller__.send(this.connectionName, "traceObj");
 }
 
 //---------------------------------------------------------------------------------------------
 
 
 public static function evalPath(o:Object, path:String) {
  var pathArray:Array = path.split(".");
  for (var i:Number = 0; i < pathArray.length; ++i) {
   if (pathArray[i].indexOf("()") > 0) {
    o = o[pathArray[i].split("()")[0]]();
   } else {
    o = o[pathArray[i]];
   }
  }
  return o;
 }

 //---------------------------------------------------------------------------------------------
 
}

使用方式:

var obj:Object = {name: "Referent Object"};
obj.getName = function(){
 return this.name;
};
var weakRef:WeakReference = new WeakReference(obj);
delete obj;
var lisObj:Object = {};
lisObj.onCallback = function(eventObj:Object):Void{
 trace("onCallback : " + eventObj.result);
};
weakRef.addEventListener("onCallback", lisObj);
weakRef.proxyObj.getName();

相關連結:
AS3 Weakly Referenced Listener 錯誤的使用方式

Read more...

2007年6月27日 星期三

FMS Client AS 自訂類別物件傳遞   [+/-]

Ticore's Blog

透過與 FMS 連線,可以共享 SharedObject 物件資料
但是資料內容僅限於 String、Number、Array 等基礎物件
不過可以使用 SharedObject.send 傳遞自訂類別的物件
以下是範例程式:

FMS SSAS:

application.onConnect = function() {
 return true;
};

自訂類別 MyClass.as:

class MyClass {
 public var name:String = "MyClass";
 public function MyClass() {
  trace("MyClass();");
 }
 public function fun():Void {
  trace("fun();");
 }
}

發布者 ActionScript:

Object.registerClass("MyClass",MyClass);
//
var nc:NetConnection = new NetConnection();
nc.onStatus = function(infoObj:Object):Void  {
 trace(infoObj.code);
 switch (infoObj.code) {
  case "NetConnection.Connect.Success" :
   so.send("getObj",new MyClass());
   break;
 }
};
nc.connect("rtmp:/so_app");
var so:SharedObject = SharedObject.getRemote("so", nc.uri);
so.connect(nc);

接受者 ActionScript:

Object.registerClass("MyClass",MyClass);
//
var nc:NetConnection = new NetConnection();
nc.onStatus = function(infoObj:Object):Void  {
 trace(infoObj.code);
 switch (infoObj.code) {
  case "NetConnection.Connect.Success" :
   break;
 }
};
nc.connect("rtmp:/so_app");
var so:SharedObject = SharedObject.getRemote("so", nc.uri);
so.getObj = function(obj) {
 trace("so.getObj();");
 trace(obj.name);
 obj.fun();
};
so.connect(nc);

最主要的關鍵步驟是 Object.registerClass("MyClass",MyClass);
同理也可以利用類似做法在 FMS SSAS 與 Client AS 之間共享類別物件

Read more...

AS3 E4X - XML 節點包覆   [+/-]

Ticore's Blog

全部子節點下移一層:

var xml:XML =
<xml>
 <node/>
</xml>;
var newNode:XML = <{"newNode"}/>;
newNode.* = xml.*;
xml.* = newNode;
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

全部子節點下移一層:

var xml:XML =
<xml>
 <node/>
 text
</xml>;
var nodeName:String = "children";
xml.* = <{nodeName}>{xml.*}</{nodeName}>;
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

個別子節點下移一層:

var xml:XML =
<xml>
 <node1/>
 text
 <node2/>
 <node3/>
</xml>;
var nodeName:String = "child";
xml.*.(parent().*[childIndex()] = <{nodeName}>{parent().*[childIndex()]}</{nodeName}>);
trace(xml.toXMLString());

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月26日 星期二

修改 FileReference 相對路徑依據方式   [+/-]

Ticore's Blog

之前介紹了三種截然不同 Flash Player Plugin 路徑行為
真是非常神奇,文件上居然都沒有提到

FileReference 這樣完全根據自身 Flash Movie 路徑的行為有時候很不方便
解決的方式很簡單,只要在主影片內宣告 function 讓其它載入的影片呼叫即可

再繼續研究影響路徑的因素...
可以發現到主要是由 FileReference 物件實體化位置所影響
這樣可以更彈性的只要動態依據參數在主影片內產生實體回傳就好
其它呼叫函式的動作都下放子影片內

http://www.dom1.com/swf1/movie1.swf
ActionScript:

System.security.allowDomain("http://www.dom2.com");

function getInstance(className:String):Object{
 return new [className]();
};

var mc:MovieClip = this.createEmptyMovieClip("mc", this.getNextHighestDepth());
mc.loadMovie("http://www.dom2.com/swf2/movie2.swf");

http://www.dom1.com/swf2/movie2.swf
ActionScript:

_parent.getInstance("flash.net.FileReference").download("file1.txt","file1.txt");

這樣 movie2.swf 會下載檔案 http://www.dom1.com/swf1/file1.txt

相關連結:
Flash Player Plugin 相關路徑行為實例
網頁上 Flash 路徑小技巧

Read more...

Flash Player Plugin 相關路徑行為實例   [+/-]

Ticore's Blog

Flash Player Plugin 在 HTML 上路徑相關的行為相當複雜
一般認知是 SWF 檔案會以 HTML 所在路徑為相對路徑起始
這只適用於大部分讀取外部資料 API 行為,loadMovie、LoadVars...

假如遇到了 NetStream 撥放外部 *.flv 檔案
或是 FileReference 便不適用了

以下分別挑選一般性的 LoadVars 以及 NetStream、FileReference 作測試
加入 Flash Object 標籤的 Base 屬性設定,以及跨網域 (cross-domain) 讀取等因素進行測試

HTML 部分不完整列出了,僅列出 Object Base、Object Src 而已
主要影片:指的是 HTML Object 明確指定路徑的 Flash Movie,非 loadMovie 讀入的影片
自身影片:指的是 ActionScript 執行所在 Flash Movie 位置,可能是主要影片或是外部讀入影片

LoadVars 相對起始路徑與依據主要影片位置相同,會受 Object Base 影響
http://localhost/html/index.html
[HTML Setting] object base:".." object src:"http://www.dom1.com/swf1/movie1.swf"
http://www.dom1.com/swf1/movie1.swf
[ActionScript] var loader:LoadVars = new LoadVars(); loader.load("swf1/file1.txt"); loadMovieNum("http://www.dom2.com/swf2/movie2.swf", 1);
http://www.dom2.com/swf2/movie2.swf
[ActionScript] var loader:LoadVars = new LoadVars(); loader.load("swf2/file2.txt"); loadMovieNum("http://www.dom3.com/swf3/movie3.swf", 2);
http://www.dom3.com/swf3/movie3.swf
[ActionScript] var loader:LoadVars = new LoadVars(); loader.load("swf3/file3.txt");
上述的程式會先讀取
http://localhost/crossdomain.xml

然後分別讀取以下路徑檔案:

http://localhost/swf1/file1.txt
http://localhost/swf2/file2.txt
http://localhost/swf3/file3.txt

*.flv 撥放相對起始位置相對起始路徑與主要影片位置相同,不受 Object Base 影響
http://localhost/html/index.html
[HTML Setting] object base:".." object src:"http://www.dom1.com/swf1/movie1.swf"
http://www.dom1.com/swf1/movie1.swf
[ActionScript] var nc:NetConnection = new NetConnection(); nc.connect(null); var ns:NetStream = new NetStream(nc); ns.play("video1.flv"); loadMovieNum("http://www.dom2.com/swf2/movie2.swf", 1);
http://www.dom2.com/swf2/movie2.swf
[ActionScript] var nc:NetConnection = new NetConnection(); nc.connect(null); var ns:NetStream = new NetStream(nc); ns.play("video2.flv"); loadMovieNum("http://www.dom3.com/swf3/movie3.swf", 2);
http://www.dom3.com/swf3/movie3.swf
[ActionScript] var nc:NetConnection = new NetConnection(); nc.connect(null); var ns:NetStream = new NetStream(nc); ns.play("video3.flv");

上述的程式分別讀取以下路徑檔案:

http://www.dom1.com/swf1/video1.flv
http://www.dom1.com/swf1/video2.flv
http://www.dom1.com/swf1/video3.flv

FileReference 相對起始路徑與自身影片位置相同,不受 Object Base 影響
http://localhost/html/index.html
[HTML Setting] object base:".." object src:"http://www.dom1.com/swf1/movie1.swf"
http://www.dom1.com/swf1/movie1.swf
[ActionScript] import flash.net.*; var file:FileReference = new FileReference(); var lisObj:Object = {}; lisObj.onComplete = function() { trace("onComplete"); loadMovieNum("http://www.dom2.com/swf2/movie2.swf", 1); }; file.addListener(lisObj); file.download("file1.txt", "file1.txt");
http://www.dom2.com/swf2/movie2.swf
[ActionScript] import flash.net.*; var file:FileReference = new FileReference(); var lisObj:Object = {}; lisObj.onComplete = function() { trace("onComplete"); loadMovieNum("http://www.dom3.com/swf3/movie3.swf", 1); }; file.addListener(lisObj); file.download("file2.txt","file2.txt");
http://www.dom3.com/swf3/movie3.swf
[ActionScript] import flash.net.*; var file:FileReference = new FileReference(); file.download("file3.txt", "file3.txt");

上述的程式分別讀取以下路徑檔案:

http://www.dom1.com/swf1/file1.txt
http://www.dom2.com/swf2/file2.txt
http://www.dom3.com/swf3/file3.txt

相關連結:
修改 FileReference 相對路徑依據方式
網頁上 Flash 路徑小技巧

Read more...

2007年6月25日 星期一

AS3 E4X 資料取出與計算   [+/-]

Ticore's Blog

使用 for 計算總合:

var xml:XML = 
<order>
 <item id='1' quantity='2'>
  <menuName>burger</menuName>
  <price>3.95</price>
 </item>
 <item id='2' quantity='2'>
  <menuName>fries</menuName>
  <price>1.45</price>
 </item>
</order>;
var total:Number = 0;
for (var pname:String in xml.item) {
 total += xml.item.@quantity[pname] * xml.item.price[pname];
}
trace(total);

使用 for each 計算總合:

var xml:XML = 
<order>
 <item id='1' quantity='2'>
  <menuName>burger</menuName>
  <price>3.95</price>
 </item>
 <item id='2' quantity='2'>
  <menuName>fries</menuName>
  <price>1.45</price>
 </item>
</order>;
var total:Number = 0;
for each (var prop:XML in xml.item) {
 total += prop.@quantity * prop.price;
}
trace(total);

使用篩選運算子 .(...) 計算總合:

var xml:XML = 
<order>
 <item id='1' quantity='2'>
  <menuName>burger</menuName>
  <price>3.95</price>
 </item>
 <item id='2' quantity='2'>
  <menuName>fries</menuName>
  <price>1.45</price>
 </item>
</order>;
var total:Number = 0;
xml.item.(total += @quantity * price);
trace(total);

兩個 XML 模擬關聯式 Table 計算總合:

var itemXML:XML =
<table>
 <entry id="0">
  <name>Item 0</name>
  <price>12</price>
 </entry>
 <entry id="1">
  <name>Item 1</name>
  <price>8</price>
 </entry>
 <entry id="2">
  <name>Item 2</name>
  <price>16</price>
 </entry>
 <entry id="3">
  <name>Item 3</name>
  <price>26</price>
 </entry>
</table>;

var recordXML:XML = 
<table>
 <entry id="0">
  <itemId>1</itemId>
  <no>22</no>
 </entry>
 <entry id="1">
  <itemId>2</itemId>
  <no>12</no>
 </entry>
 <entry id="2">
  <itemId>0</itemId>
  <no>8</no>
 </entry>
 <entry id="3">
  <itemId>3</itemId>
  <no>13</no>
 </entry>
</table>;
var total:Number = 0;
recordXML.entry.(total += (itemXML.entry.(@id == itemId).price * no));
trace(total);

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月23日 星期六

網頁上 Flash 路徑小技巧   [+/-]

Ticore's Blog

一般製作 HTML 網頁內嵌 Flash SWF 時
為了管理方便,通常會把 *.html、*.swf 檔案放在不同資料夾下
假如 SWF 內還有需要動態讀取其它的檔案
預設情況下,Flash Player Plugin 會以 .html 所在路徑為起始預設路徑
這樣測試起來不太方便

其實 Flash Object 標籤有一個 Base Attribute 可用
可以用來設定起始路徑位置

像以下將 Base 設為 ".",Flash Player Plugin 就會以 .swf 檔案所在路徑為起始

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
 codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0"
    name="loader" width="300" height="200" align="middle" id="loader">
  <param name="allowScriptAccess" value="sameDomain" />
  <param name="allowFullScreen" value="false" />
  <param name="movie" value="swf/loader.swf" />
  <param name="quality" value="high" />
  <param name="bgcolor" value="#ffffff" />
  <param name="base" value=".">
  <embed src="swf/loader.swf" width="300" height="200" align="middle" quality="high"
   bgcolor="#ffffff" name="loader" allowScriptAccess="sameDomain"
    allowFullScreen="false" type="application/x-shockwave-flash"
    pluginspage="http://www.macromedia.com/go/getflashplayer" base="." />
</object>

或者也可以設為其它 domain,只是需要注意 Corssdomain Security

另外需要注意,這個方式對撥放外部 *.flv 路徑沒有效果喔!

相關連結:
Flash OBJECT and EMBED tag attributes
Flash Player Plugin 相關路徑行為實例
修改 FileReference 相對路徑依據方式

Read more...

2007年6月22日 星期五

Flash 9 AS3 移除 Render Event Bug   [+/-]

Ticore's Blog

最近在測試 AS3 時間性事件時,又發現了一個 Render Event Bug
當一個 DisplayObject 註冊多個 Render 事件後
使用 removeEventListener 移除一個 Render 事件
會造成該 DisplayObject 所有 Render 事件監聽器都失效
需要重新加入一個 Render 事件監聽器,才能讓其它監聽器恢復作用

以下是 Bug Demo 程式
main class:

package {
 import flash.display.*;
 import flash.events.*;
 import flash.utils.*;
 
 public class main extends MovieClip {
  
  var mc:MovieClip;
  
  public function main():* {
   stage.frameRate = 1;
   mc = new MC();
   mc.name = "MC";
   this.addChild(mc);
   setInterval(onInterval, 10);
  }
  
  public function onInterval():* {
   trace("onInterval:" + getTimer());
   stage.invalidate();
  }
  
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

MC class:

package {
 import flash.display.*;
 import flash.events.*;
 
 public class MC extends MovieClip {

  public function MC():* {
   this.addEventListener(Event.ENTER_FRAME,enterFrameHandler1);
   this.addEventListener(Event.ENTER_FRAME,enterFrameHandler2);
   this.addEventListener(Event.RENDER,renderHandler1);
   this.addEventListener(Event.RENDER,renderHandler2);
   this.addEventListener(Event.RENDER,renderHandler3);
  }
  
  public function enterFrameHandler1(e:Event):void {
   var mc:MovieClip = e.target as MovieClip;
   trace("onEnterFame Event 1");
   e.target.removeEventListener(Event.ENTER_FRAME, e.target.enterFrameHandler1);
  }
  
  public function enterFrameHandler2(e:Event):void {
   var mc:MovieClip = e.target as MovieClip;
   trace("onEnterFame Event 2");
  }
  
  public function renderHandler1(e:Event):void {
   var mc:MovieClip = e.target as MovieClip;
   trace("onRender Event 1");
   e.target.removeEventListener(Event.RENDER, e.target.renderHandler1);
   // 重新加入一個 Render Event
   //e.target.addEventListener(Event.RENDER, function(e:Event):*{});
  }
  
  public function renderHandler2(e:Event):void {
   var mc:MovieClip = e.target as MovieClip;
   trace("onRender Event 2");
  }
  
  public function renderHandler3(e:Event):void {
   var mc:MovieClip = e.target as MovieClip;
   trace("onRender Event 3");
  }
 }
}
// Ticore's Blog - http://ticore.blogspot.com/

輸出結果:

onEnterFame Event 1
onEnterFame Event 2
onInterval:117
onRender Event 1
onRender Event 2
onRender Event 3
onInterval:206
onInterval:312
onInterval:406
onInterval:512
onInterval:607
onInterval:711
onInterval:806
onInterval:912
onInterval:1018
onEnterFame Event 2
onInterval:1113
onInterval:1207
onInterval:1315
onInterval:1406
onInterval:1512
onInterval:1606
onInterval:1706
onInterval:1807
onInterval:1906
onInterval:2006
onInterval:2106
onEnterFame Event 2
onInterval:2206
onInterval:2306
onInterval:2406
onInterval:2509
onInterval:2606

從輸出結果可以發現,雖然只有移除一個 Render 事件
但是另外兩個 Render 事件都不見了

該 Bug 已經在以下 Flash Player 版本測試過確實會發生
Flash Player 9.0.45.0
Flash Player 9.0.60.120
Flash Player 9.0.60.235
Flash Player 9.0.64.0
Flash Player 9.0.115.0
Flash Player 9.0.124.0
Flash Player 9.0.159.0

至於 Flash Player 10 似乎完全沒有這個 Bug
只會發生在 Flash Player 9,還挺奇怪的

Read more...

2007年6月21日 星期四

Flash 9 AS3 時間性事件混合測試   [+/-]

Ticore's Blog

這次將 Flash 9 AS3 與時間相關的事件一併納入測試
與 FPS 直接相關的 frameScript、enterFrame、render 事件
還有 setInterval 事件 (與 Timer 類似)
最後還有一個簡單的 Mouse Down 事件,主要是用來觀察與時間性事件之間的關係

開一 fla 文件,建立含有三個影格的 MovieClip,設定 Class Name 為 "MC"
套用以下 document class:

package {
 import flash.display.*;
 import flash.events.*;
 import flash.utils.*;

 public class main extends MovieClip {

  var mc1:MovieClip;
  var mc2:MovieClip;
  var mc3:MovieClip;
  var mcAry:Array = [];
  
  //
  //=================================================================================
  //
  
  public function main() {
   init();
  } 
  public function init() {
   
   for (var i:Number = 1 ; i <= 3 ; ++i) {
    var mc:MovieClip = new MC();
    this["mc" + i] = mc;
    mcAry.push(mc);
    mc.name = "MC" + i;
    mc.frameAction = frameAction;
    var fa:Function = createFrameAction(mc, "frameAction");
    mc.addFrameScript(0, fa, 1, fa, 2, fa);
    mc.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    mc.addEventListener(Event.RENDER, renderHandler);
    mc.gotoAndPlay(2);
   }
   
   reparent();
   setInterval(reparent, 6000);
   setInterval(onInterval, 1);
   stage.invalidate();
   stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
   
  }
  
  //
  //=================================================================================
  //
  
  public function reparent():void {
   
   mcAry.sort(sortOnRandom);
   trace("=> Reparent To:root > ", mcAry[0].name + " > " + mcAry[1].name + " > " + mcAry[2].name);
   
   for(var i:Number = 0 ; i < mcAry.length ; ++i) {
    if(mcAry[i].parent != null) {
     mcAry[i].parent.removeChild(mcAry[i]);
    }
   }
   
   this.addChild(mcAry[0]);
   mcAry[0].addChild(mcAry[1]);
   mcAry[1].addChild(mcAry[2]);
   
  }
  
  public function sortOnRandom(a:*, b:*):Number{
   return Math.floor(Math.random() * 3) - 1;
  }
  
  public function createFrameAction(mc:MovieClip, fun:String):Function {
   return function():void {
    mc[fun]();
   };
  }
  public function getFullPath(mc:DisplayObject):String {
   if (mc == null) { return ""; }
   var path:String = mc.name;
   var target:DisplayObjectContainer = mc.parent;
   while (target != stage) {
    path = target.name + "." + path;
    target = target.parent;
   }
   return path;
  }
  
  //
  //=================================================================================
  //
  
  public var mouseDownHandler:Function = function(e:Event):void {
   trace("Mouse Down");
  };
  
  public var frameAction:Function = function():void {
   trace("Frame Script " + this.currentFrame + ":" + getFullPath(this));
  };
  
  public var enterFrameHandler:Function = function(e:Event):void{
   var mc:MovieClip = e.target as MovieClip;
   trace("onEnterFame " + mc.currentFrame + ":" + getFullPath(mc));
  };
  
  public var renderHandler:Function = function(e:Event):void{
   var mc:MovieClip = e.target as MovieClip;
   trace("onRender " + mc.currentFrame + ":" + getFullPath(mc));
  };
  
  public var onInterval:Function = function():void{
   trace("onInterval:" + getTimer());
   stage.invalidate();
  };
  
  //
  //=================================================================================
  //
 }
}

輸出結果如下:

=> Reparent To:root >  MC1 > MC2 > MC3
Frame Script 2:root1.MC1
Frame Script 2:root1.MC1.MC2
Frame Script 2:root1.MC1.MC2.MC3
onEnterFame 2:root1.MC1
onEnterFame 2:root1.MC1.MC2
onEnterFame 2:root1.MC1.MC2.MC3
onInterval:1120
onRender 2:root1.MC1
onRender 2:root1.MC1.MC2
onRender 2:root1.MC1.MC2.MC3
onInterval:2053
onInterval:3078
onInterval:4266
onInterval:5125
=> Reparent To:root >  MC1 > MC2 > MC3
onInterval:6149
onInterval:7174
onInterval:8197
Mouse Down
onInterval:9221
onInterval:10246
onInterval:11270
onEnterFame 3:root1.MC1
onEnterFame 3:root1.MC1.MC2
onEnterFame 3:root1.MC1.MC2.MC3
=> Reparent To:root >  MC2 > MC1 > MC3
onInterval:12293
Frame Script 3:root1.MC2
Frame Script 3:root1.MC2.MC1
Frame Script 3:root1.MC2.MC1.MC3
onRender 3:root1.MC2.MC1
onRender 3:root1.MC2
onRender 3:root1.MC2.MC1.MC3
onInterval:13317

各位也可以調整參數反覆測試,可以觀察到一些特性:

  • 主要分為三種 Phase:Enter Frame Event Phase、Frame Script Phase、Render Event Phase, 三種階段也是按此順序執行
    (首輪 Frame Script Phase 優先可能又是例外)
  • Frame Script 執行順序受到階層順序的影響,上層較優先; Enter Frame Event 與 Render Event 則是依照建立順序執行
  • Interval Event 與 Mouse Event 似乎無法插入三種 Phase 任一執行期內, 僅能插入於 Phase 之間的空檔執行
  • FPS 越小 Render Event Phase 與 Enter Frame Event Phase 時間空隙越大

相關連結:
Flash Player 10 beta - 新的影格事件
Flash 9 AS3 FrameScript + Reparenting 惡搞測試
Flash Player 8 AS2 影格程式執行順序
AS3 Tip - 讓動態加入影格程式取得目前 MovieClip 參考

Read more...

AS3 E4X - XML 節點交換   [+/-]

Ticore's Blog

先把節點複製出來,再插入:

var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
</xml>;
var node1:XML = xml.*[0].copy();
var node2:XML = xml.*[1].copy();
xml.*[0] = node2;
xml.*[1] = node1;
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

取得節點參考,刪除子節點後,再插入:

var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
</xml>;
var node1:XML = xml.*[0];
var node2:XML = xml.*[1];
delete xml.*;
xml.*[0] = node2;
xml.*[1] = node1;
trace(xml.toXMLString());
trace(xml.*[0].childIndex());
trace(xml.*[1].childIndex());

// Ticore's Blog - http://ticore.blogspot.com/
var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
 <node3>3</node3>
</xml>;
var node1:XML = xml.*[0];
var node2:XML = xml.*[1];
var node3:XML = xml.*[2];
xml.*[0] = <n />;
xml.*[2] = <n />;
trace(xml.toXMLString());
xml.*[0] = node3;
xml.*[2] = node1;
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

交換失敗例子:

var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
 <node3>3</node3>
</xml>;

var node:XML = xml.*[0];
xml.*[0] = xml.*[2];
xml.*[2] = <n />;
trace(xml.toXMLString());

使用 replace 交換節點:

var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
 <node3>3</node3>
</xml>;
var node:XML = xml.*[0];
xml.replace(0, xml.*[2]);
xml.replace(2, node);
trace(xml.toXMLString());

使用 replace 交換節點:

var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
 <node3>3</node3>
</xml>;
var node1:XML = xml.*[0];
var node2:XML = xml.*[2];
xml.replace(0, "");
xml.replace(2, "");
xml.*[0] = node2;
xml.*[2] = node1;
trace(xml.toXMLString());
trace(xml.*[0].childIndex());
trace(xml.*[1].childIndex());
trace(xml.*[2].childIndex());

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

AS3 E4X - 插入 XML 節點   [+/-]

Ticore's Blog

利用 appendChild 插入節點:

XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
var xml:XML = 
<xml attr1="1">
</xml>;
xml.appendChild(<node />);
xml.appendChild(<!-- comment -->);
xml.appendChild(<? instruction ?>);
xml.appendChild("text");
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

利用 += 運算子插入節點:

XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
var xml:XML = 
<xml attr1="1">
</xml>;
xml.* += <node />;
xml.* += <!-- comment -->;
xml.* += <? instruction ?>;
xml.* += XML("text");
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

直接指定節點名稱與索引插入:

var xml:XML = 
<xml attr1="1">
 text
</xml>;
xml.node[0] = "node text 1";
xml.node[1] = "node text 2";
trace(xml.toXMLString());

插在子節點 0 之後:

var xml:XML = 
<xml attr1="1">
 text
</xml>;
xml.*[0] += <node>1</node>;
xml.*[0] += <node>2</node>;
xml.*[0] += <node>3</node>;
trace(xml.toXMLString());
var xml:XML = 
<xml attr1="1">
 text
</xml>;
xml.insertChildAfter(xml.*[0], <node>1</node>);
xml.insertChildAfter(xml.*[0], <node>2</node>);
xml.insertChildAfter(xml.*[0], <node>3</node>);
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

插在子節點 0 之前:

var xml:XML = 
<xml attr1="1">
 text
</xml>;
xml.* = <node>1</node> + xml.*;
xml.* = <node>2</node> + xml.*;
xml.* = <node>3</node> + xml.*;
trace(xml.toXMLString());
var xml:XML = 
<xml attr1="1">
 text
</xml>;
xml.insertChildBefore(xml.*[0], <node>1</node>);
xml.insertChildBefore(xml.*[0], <node>2</node>);
xml.insertChildBefore(xml.*[0], <node>3</node>);
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

AS3 Tip - 讓動態加入影格程式取得目前 MovieClip 參考   [+/-]

Ticore's Blog

當用 addFrameScript 動態指定 MovieClip 影格程式時
function 內的 this 一般都是指到原始宣告位置的 Class Instance
或者是指向 global 物件
這樣用起來實在不方便

以下使用 unbound function 加上一個公用函式
讓 this 可以取得目前 MovieClip 參考
首先建立公用函式:

package {
 import flash.display.*;
 public function delegate (mc:MovieClip, fun:String):Function {
  return function():*{
   mc[fun]();
  }
 }
}

宣告 document class:

package {
 import flash.display.*;
 public class main extends MovieClip {
  public function main () {
   
   var mc:MC = new MC();
   mc.frameAction = function ():void{
    trace(this.name, this.currentFrame);
   }
   var fun:Function = delegate(mc, "frameAction");
   mc.addFrameScript(0, fun, 1, fun);
   
  }
 }
}

建立 fla 文件,並且建立一個三個影格的 MovieClip,輸出為 "MC"

相關連結:
ActionScript 3.0 beta 2 Bound Function
ActionScript 3.0 beta 1 Global Object
AS 3.0 利用 function scope 暫存變數
AS 2.0 將參數與 function 綁在一起

Read more...

2007年6月20日 星期三

Flash 9 AS3 FrameScript + Reparenting 惡搞測試   [+/-]

Ticore's Blog

繼之前 Flash Player 8 AS2 影格程式執行順序
再來測試 Flash 9 AS3 影格程式執行順序
不過如 qop 測試結果,AS3 都改外層 Frame Script 優先執行

所以要加點料,把 AS3 新功能 Reparenting 加入測試條件
首先用 Flash CS3 建立空白文件
root 影格拉到三格,fps 設為 1
於 Library 建立一個 MovieClip,也是一樣影格拉到三格
然後設定輸出給 ActionScript 使用,Class 命名為 "MC"
最後將文件套用 document class:

package {
 import flash.display.*;
 import flash.events.*;
 import flash.utils.*;

 public class main extends MovieClip {

  var mc1:MovieClip;
  var mc2:MovieClip;
  var mc3:MovieClip;
  var mcAry:Array = [];
  
  public function main() {
   var obj:Object = {};
   init();
  } 
  public function init() {
   
   for (var i:Number = 1 ; i <= 3 ; ++i) {
    var mc:MovieClip = new MC();
    this["mc" + i] = mc;
    mcAry.push(mc);
    mc.name = "MC" + i;
    mc.frameAction = frameAction;
    var fa:Function = createFrameAction(mc, "frameAction");
    mc.addFrameScript(0, fa, 1, fa, 2, fa);
    mc.gotoAndPlay(2);
   }
   
   var fa0:Function = createFrameAction(this, "frameAction");
   this.addFrameScript(0, fa0, 1, fa0, 2, fa0);
   this.gotoAndPlay(2);
   
   reparent();
   
   setInterval(reparent, 3000);
  }
  
  public function reparent():void {
   
   mcAry.sort(sortOnRandom);
   trace("\nReparent To:root > ", mcAry[0].name + " > " + mcAry[1].name + " > " + mcAry[2].name);
   
   this.numChildren > 0 ? this.removeChildAt(this.numChildren - 1) : null;
   mc1.numChildren > 0 ? mc1.removeChildAt(0) : null;
   mc2.numChildren > 0 ? mc2.removeChildAt(0) : null;
   mc3.numChildren > 0 ? mc3.removeChildAt(0) : null;
   
   this.addChild(mcAry[0]);
   mcAry[0].addChild(mcAry[1]);
   mcAry[1].addChild(mcAry[2]);
   
  }
  
  public function sortOnRandom(a:*, b:*):Number{
   return Math.floor(Math.random() * 3) - 1;
  }
  
  public function createFrameAction(mc:MovieClip, fun:String):Function {
   return function():void {
    mc[fun]();
   };
  }
  
  public var frameAction:Function = function():void {
   var path:String = this.name;
   var target:DisplayObjectContainer = this.parent;
   while (target != stage) {
    path = target.name + "." + path;
    target = target.parent;
   }
   trace("Frame " + this.currentFrame + " Running:" + path);
  }
 }
}

上述程式會動態建立三個 MC
並且會以亂數順序加入到 root 之下
測試影格程式是否會受到加入順序影響
每三秒鐘還會重新洗牌一次,夠惡搞了吧!

測試影片,可以看到輸出結果:

Reparent To:root >  MC1 > MC3 > MC2
Frame 2 Running:root1
Frame 2 Running:root1.MC1
Frame 2 Running:root1.MC1.MC3
Frame 2 Running:root1.MC1.MC3.MC2
Frame 3 Running:root1
Frame 3 Running:root1.MC1
Frame 3 Running:root1.MC1.MC3
Frame 3 Running:root1.MC1.MC3.MC2
Frame 1 Running:root1
Frame 1 Running:root1.MC1
Frame 1 Running:root1.MC1.MC3
Frame 1 Running:root1.MC1.MC3.MC2

Reparent To:root >  MC3 > MC1 > MC2
Frame 2 Running:root1
Frame 2 Running:root1.MC3
Frame 2 Running:root1.MC3.MC1
Frame 2 Running:root1.MC3.MC1.MC2
Frame 3 Running:root1
Frame 3 Running:root1.MC3
Frame 3 Running:root1.MC3.MC1
Frame 3 Running:root1.MC3.MC1.MC2
Frame 1 Running:root1
Frame 1 Running:root1.MC3
Frame 1 Running:root1.MC3.MC1
Frame 1 Running:root1.MC3.MC1.MC2

果然不負眾望,依照期望方式執行~

接下來,再調整洗牌時間間隔為 300 ms
可以看到輸出結果:

Reparent To:root >  MC1 > MC2 > MC3
Frame 2 Running:root1
Frame 2 Running:root1.MC1
Frame 2 Running:root1.MC1.MC2
Frame 2 Running:root1.MC1.MC2.MC3

Reparent To:root >  MC1 > MC2 > MC3

Reparent To:root >  MC1 > MC2 > MC3

Reparent To:root >  MC1 > MC2 > MC3
Frame 3 Running:root1
Frame 3 Running:root1.MC1
Frame 3 Running:root1.MC1.MC2
Frame 3 Running:root1.MC1.MC2.MC3

Reparent To:root >  MC1 > MC2 > MC3

Reparent To:root >  MC1 > MC2 > MC3

Reparent To:root >  MC1 > MC2 > MC3
Frame 1 Running:root1
Frame 1 Running:root1.MC1
Frame 1 Running:root1.MC1.MC2
Frame 1 Running:root1.MC1.MC2.MC3

Reparent To:root >  MC1 > MC2 > MC3

Reparent To:root >  MC1 > MC3 > MC2

Reparent To:root >  MC3 > MC1 > MC2

Reparent To:root >  MC3 > MC1 > MC2
Frame 2 Running:root1
Frame 2 Running:root1.MC3
Frame 2 Running:root1.MC3.MC1
Frame 2 Running:root1.MC3.MC1.MC2

Frame Script 與 setInterval 函式的執行階段似乎是井水不泛河水
不管 interval 多小,都無法插入 Frame Script 執行階段內

相關連結:
Flash Player 10 beta - 新的影格事件
Flash 9 AS3 時間性事件混合測試
Flash Player 8 AS2 影格程式執行順序
AS3 Tip - 讓動態加入影格程式取得目前 MovieClip 參考

Read more...

2007年6月19日 星期二

Flash Player 8 AS2 影格程式執行順序   [+/-]

Ticore's Blog

看到 qop 的文章,也稍微測試一下影格程式的執行順序
在 Flash 8 AS2 的測試結果出人意料之外!

只有在 MovieClip 實體預先放在 stage 上
且目標 Frame Script 都是放在影格 1
第一次 loop 才是外層 Frame Script 先執行
跑第二次 loop 時,就會變成最內層 Frame Script 先執行

簡單的輸出範例:

// loop 1
_level0.mc
_level0.mc.mc
_level0.mc.mc.mc
// loop 2
_level0.mc.mc.mc
_level0.mc.mc
_level0.mc
// loop 3
_level0.mc.mc.mc
_level0.mc.mc
_level0.mc
// loop 4
_level0.mc.mc.mc
_level0.mc.mc
_level0.mc

其它以 AS 動態建立 MovieClip 實體測試條件
則完全都是內層 Frame Script 先執行

測試檔案下載

相關連結:
Flash Player 10 beta - 新的影格事件
Flash 9 AS3 時間性事件混合測試
Flash 9 AS3 FrameScript + Reparenting 惡搞測試
AS3 Tip - 讓動態加入影格程式取得目前 MovieClip 參考

Read more...

AS3 E4X - 刪除 XML 節點   [+/-]

Ticore's Blog

刪除單一子節點:

var xml:XML =
<xml>
 <node>1</node>
 <node>2</node>
 <node>3</node>
 <node>4</node>
 <node>5</node>
 <node>6</node>
</xml>;
delete xml.*[0];
trace(xml.toXMLString());
delete xml.node[0];
trace(xml.toXMLString());
delete xml["node"][0];
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

刪除全部子節點:

var xml:XML =
<xml>
 <node>1</node>
 <node>2</node>
 <node>3</node>
 <node>4</node>
 <node>5</node>
 <node>6</node>
</xml>;
delete xml.*;
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/
var xml:XML =
<xml>
 <node>1</node>
 <node>2</node>
 <node>3</node>
 <node>4</node>
 <node>5</node>
 <node>6</node>
</xml>;
delete xml["node"];
trace(xml.toXMLString());

用篩選運算子刪除所有 Text 節點:

XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
var xml:XML =
<xml>
 <node>
  <n />
  <? ins ?>
  text1
  <node>text2</node>
 </node>
 text3
</xml>;
var texts:XMLList = xml..*.(nodeKind() == "text" ?
    delete parent().*[childIndex()] : false);
trace(xml.toXMLString());
trace(texts.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

利用 prototype function 刪除所有 Text 節點:

XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
var xml:XML =
<xml>
 <node>
  <n />
  <? ins ?>
  text
  <node>text</node>
 </node>
 text
</xml>;
XML.prototype.process = function():void{
 if (this.nodeKind() == "text") {
  delete this.parent().*[this.childIndex()];
 }
};
xml..*.(process());
trace(xml.toXMLString());

刪除第一層、第二層 Text 子節點:

XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
var xml:XML =
<xml>
 <node>
  <n />
  <? ins ?>
  text
  <node>text</node>
 </node>
 text
</xml>;
XML.prototype.process = function():void{
 if (this.nodeKind() == "text") {
  delete this.parent().*[this.childIndex()];
 }
};

xml.*.(process());
xml.*.*.(process());
trace(xml.toXMLString());

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月18日 星期一

自製 Flash、Flex、FMS LvieDocs 搜尋引擎外掛   [+/-]

Ticore's Blog

Ticore's Search Plugins

Add Flex 2.01 Search Plugin
Add Flash 8 Search Plugin
Add Flash CS3 Search Plugin
Add FMS 2 Search Plugin
Add Flash CS3 AS 3 Ref. Search Plugin
Add Flex 2.01 AS 3 Ref. Search Plugin
Add Flash CS3 TW Search Plugin
Add Flash CS3 AS 3 Ref. TW Search Plugin

Read more...

AS3 E4X Tip - 你拿到的是 XML or XMLList?   [+/-]

Ticore's Blog

在 AS3 E4X 四個相關 Class 中
XML、XMLList 非常相近,容易讓人混淆
XML 主要是用來描述單一 XML 物件,具有一個 root node
XMLList 則是 XML 物件集合,沒有 root node,有點類似陣列
許多的 XML 相關的操作,都是回傳 XMLList

以下做一些測試,看看拿到的是什麼型別:

var xml:XML =
<xml attr1="A1" attr2="A2">
 text
 <node/>
 <node/>
 <node/>
</xml>;
trace((describeType(xml)).@name);               // XML
trace((describeType(xml.name())).@name);        // QName
trace((describeType(xml.@*)).@name);            // XMLList
trace((describeType(xml.@*[0])).@name);         // XML
trace((describeType(xml.attributes())).@name);  // XMLList
trace((describeType(xml.*)).@name);             // XMLList
trace((describeType(xml.children())).@name);    // XMLList
trace((describeType(xml.node)).@name);          // XMLList
trace((describeType(xml.node[0])).@name);       // XML
trace((describeType(xml.node.(true))).@name);   // XMLList
trace((describeType(xml.child("node"))).@name); // XMLList


// Ticore's Blog - http://ticore.blogspot.com/

XMLList 還有一個很重要特性
當 XMLList 物件內元素數量為 1 時,可以直接當作 XML 來進行操作

var xml:XML =
<xml>
 <node name="Node"/>
</xml>;
trace(xml.node.(true).@name); // Node
trace((describeType(xml.child("node"))).@name); // XMLList

// Ticore's Blog - http://ticore.blogspot.com/

當 XML、XMLList 同時具有相同名稱 prototype function 時
上述的自動轉換功能又有些不一樣

XML.prototype.foo = function():*{
 trace("XML.foo();");
}
XMLList.prototype.foo = function():*{
 trace("XMLList.foo();");
}

var xml:XML =
<xml>
 <node/>
</xml>;
(xml.node as Object).foo(); // XMLList.foo();
delete XMLList.prototype.foo;
(xml.node as Object).foo(); // XML.foo();

由 output 可以發現
對單一元素 XMLList 物件呼叫 prototype function 時
AVM 會先檢查 XMLList.prototype
假如沒有,才會轉成 XML 呼叫

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

AS3 E4X 技巧 - 替 XML 添加 prototype fnuction   [+/-]

Ticore's Blog

AS3 XML、XMLList 都是屬於內建型別
雖然 E4X 功能已經非常強,function 畢竟是有限的
API 文件上可以查到 XML 是屬於 public final dynamic class,無法被繼承
理論上,應該是可以利用 prototype function 加以擴充的

以下嘗試利用 prototype function 加以擴充 XML 物件的 function

首先直接替 XML 添加 prototype function

var myFun = function():* {
 trace("myFun : " + this.toXMLString());
}
XML.prototype.myFun = myFun;
try {
 (<xml/>).myFun();
} catch (e:Error) {
 trace(e)
}

可以通過編譯,但是會出現警告訊息
執行時,也會有些怪異的情況出現

Warning: 3594: myFun is not a recognized method of the dynamic class XML.

這是由於 XML 屬於特殊類別
XML 覆寫了許多運算子
直接呼叫添加的 prototype fnuction 會讓 AVM 無法分辨是要操作 XML Element 還是要呼叫 function

只要先把 XML 物件轉型為 Object 就可以了:

var myFun = function():* {
 trace("myFun : " + this.toXMLString());
}
XML.prototype.myFun = myFun;
try {
 (<xml/> as Object).myFun();
} catch (e:Error) {
 trace(e)
}

同理,XMLList 也可以用類似的做法添加~

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月17日 星期日

AS3 E4X - XML Attribute 相關操作   [+/-]

Ticore's Blog

取出目標節點全部 Attributes:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node />
</xml>;
trace(xml.@*);
trace(xml.@["*"]);
trace(xml["@*"]);
trace(xml.attributes());
trace(xml.attribute("*"));

列舉全部節點 Attributes:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
</xml>;
trace(xml..@["*"]);
trace(xml..@*);

// Ticore's Blog - http://ticore.blogspot.com/

取出特定 Attribute:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node />
</xml>;
trace(xml.@attr1);
trace(xml.@attr1[0]);
trace(xml.@["attr" + 1]);
trace(xml.@["attr" + 2]);
trace(xml["@attr" + 1]);
trace(xml["@attr" + 2]);
trace(xml["@*"][0]);
trace(xml.@["*"][0]);
trace(xml.attribute("attr1"));
trace(xml.attributes()[0]);

// Ticore's Blog - http://ticore.blogspot.com/

透過 Attribute 物件取得相關參考:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node />
</xml>;
trace(xml.@attr1.name());
trace(xml.@attr1.parent());

修改 Attribute 物件名稱:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node />
</xml>;
xml.@attr1.setName("xxx");
trace(xml);

設定 Attribute Value:

var xml:XML = 
<xml>
 <node />
</xml>;
xml.@attr1 = "Attribute 1";
xml.@["attr2"] = "Attribute 2";
xml["@attr" + 3] = "Attribute 3";
trace(xml);

交換兩節點全部 Attributes:

var xml:XML = 
<xml>
 <node1 n1attr1="Node 1 Attribute 1" n1attr2="Node 1 Attribute 2"/>
 <node2 n2attr1="Node 2 Attribute 2" n2attr2="Node 2 Attribute 2"/>
</xml>;
var tmp1:XMLList = xml.node1.@*;
var tmp2:XMLList = xml.node2.@*;
delete xml.node1.@*;
delete xml.node2.@*;
tmp2.(xml.node1.@[name()] = toString());
tmp1.(xml.node2.@[name()] = toString());
trace(xml);

// Ticore's Blog - http://ticore.blogspot.com/

產生怪異的 Attributes:

var xml:XML = 
<xml>
 <node />
</xml>;
xml["@"] = "";
xml["@@"] = "@";
xml["@."] = "@";
xml["@>"] = "@";
xml["@<"] = "@";
xml["@?"] = "@";
xml["@/"] = "@";
xml["@="] = "@";
xml["@\n"] = "@";
xml["@\r"] = "@";
xml["@\b"] = "@";
trace(xml);

刪除 root 以外全部 Attributes:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node>
  <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 </node>
</xml>;
delete xml..*.@["*"];
trace(xml.toXMLString());

刪除全部 Attributes:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node>
  <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 </node>
</xml>;
xml..@*.(delete parent().@[name()]);
trace(xml.toXMLString());

刪除所有指定節點 Attributes:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node>
  <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 </node>
</xml>;
xml..node.@*.(delete parent().@[name()]);
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

刪除所有特定內容 Attributes:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node>
  <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 </node>
</xml>;
xml..@*.(toString() == "Node Attribute 1" ? delete parent().@[name()] : false);
trace(xml.toXMLString());

修改所有特定內容 Attributes 名稱:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2">
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 <node>
  <node  attr1="Node Attribute 1" attr2="Node Attribute 2" />
 </node>
</xml>;
xml..@*.(toString() == "Node Attribute 1" ? setName("newAttr") : false);
trace(xml.toXMLString());

// Ticore's Blog - http://ticore.blogspot.com/

改變 Attributes 先後順序:

var xml:XML = 
<xml attr1="Attribute 1" attr2="Attribute 2" attr3="Attribute 3">
</xml>;
trace(xml.toXMLString());

var attrs:XMLList = xml.@*;
xml.@*.(delete parent().@[name()]);

for (var i:Number = attrs.length() - 1 ; i >= 0  ; --i) {
 xml.@[attrs[i].name()] = attrs[i];
}
trace(xml.toXMLString());

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

用 @* 指定 Attributes 造成 Flash Player 9 Crash   [+/-]

Ticore's Blog

又是一個會造成 Flash Player 9 當機的 AS3 語法
該語法可通過編譯,也沒有特殊邏輯運算
但是執行起來會讓 Flash Player 9 整個掛掉

AS3 程式如下:

var xml:XML = 
<xml>
 <node1 attr1="Attribute 1" attr2="Attribute 2"/>
 <node2/>
</xml>;
var attributes:XMLList = xml.node1.@*;
try {
 xml.node2.@* = attributes;
 xml.node2.@* += attributes;
} catch (e:Error) {
 trace(e);
}
trace(xml);

// Ticore's Blog - http://ticore.blogspot.com/

請注意,try{...}catch(e){...} 在此沒有作用,還是會 Crash

實際測試過會掛掉的版本:
Flash Player 9.0.45.0
Flash Player 9.0.47.0
Flash Player 9.0.60.120
Flash Player 9.0.60.184
Flash Player 9.0.60.235
Flash Player 9.0.64.0
Flash Player 9.0.115.0
Flash Player 9.0.124.0
Flash Player 10.0.2.54
Flash Player 10.0.12.29
Flash Player 10.0.12.36
Flash Player 10.0.22.87

相關連結:
一行 AS3 程式讓 Flash Player 10 死機 Part 5
一行 AS3 程式讓 Flash Player 9 死機 Part 4
一行 AS3 程式讓 Flash Player 9 死機 Part 3
一行 AS3 程式讓 Flash Player 9 死機 Part 2
一行 AS3 程式讓 Flash Player 9 死機
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

Flex Tip - 不要在別人的事件中,處理自己的事情   [+/-]

Ticore's Blog

Flex 的 graphic component 事件機制比較複雜
除了 AS3 DisplayObject 的 Dom Event Flow 之外
Flex UIComponent 本身還有度量尺寸的 Event Flow
當 stage 發生 resize 事件時 (Bubbling Phase),並沒有辦法確保子物件已經完成 resize 動作

以下的程式是布魯斯小龍在問題 flash長寬的問題... 提出
該程式在 stage.resize 事件中 tarce 處理子物件與子子物件的大小

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="absolute" creationComplete="init();">
   <mx:Script>
      <![CDATA[
          private function init():void{
             this.addEventListener(Event.RESIZE,stageResize);
             //stage.addEventListener(Event.RESIZE,stageResize);
          }

         private function stageResize(e:Event):void{
                trace("Application寬度:"+this.width);
                trace("myBox寬度:"+myBox.width);
                trace("stage寬度:"+stage.width);
          }      
      ]]>
   </mx:Script>
   <mx:Canvas id="myBox" x="0" y="0" width="100%"
     height="100%" backgroundColor="#ffffff">
   </mx:Canvas>   
</mx:Application>

可以發現在 stage resize 事件中,無法正確的得到子物件的尺寸

以下則是修改過的 MXML 程式,可以 trace 出 UIComponent 正確的大小:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
 layout="absolute"
 creationComplete="init();"
 resize="resizeHandler(event);">
   <mx:Script>
      <![CDATA[
          private function resizeHandler(e:Event):void{
           trace(e.target.name, e.target.width);
          }
      ]]>
   </mx:Script>
   <mx:Canvas id="myBox" x="0" y="0" width="100%" height="100%"
    backgroundColor="#ffffff" resize="resizeHandler(event);">
   </mx:Canvas>
</mx:Application>
Read more...

2007年6月15日 星期五

含有尺規行號的 DIV 捲動區塊   [+/-]

Ticore's Blog

由於常常需要貼程式碼
survey 了一個不錯了程式碼標記工具 dp.SyntaxHighlighter
就是目前這個 Blog 中使用的~
後來又花了一些時間進行改版的動作
主要是加上行號尺規捲動功能

以下便是用 DIV、JavaScript 做出來的雛型:

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150

原始碼:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Code Area</title>
<style type="text/css">
<!--
.codeArea {
 font-size: 12px;
 line-height: 14px;
 position: relative;
 width: 300px;
 height: 200px;
 border: solid 1px #333333;
 overflow: scroll;
 font-family: Consolas;
}
.codeArea div {
 position:absolute;
 padding: 0px 0px 0px 0px;
}
.codeArea #gutter {
 background-color: #EEEEEE;
 left:0px;
 top:14px;
 width:40px;
}
.codeArea #column {
 background-color: #EEEEEE;
 left: 40px;
 top: 0px;
 white-space: nowrap;
}
.codeArea #content {
 left: 40px;
 top:14px;
}
.codeArea #block {
 left:0px;
 top:0px;
 width: 40px;
 height: 14px;
 background-color: #EEEEEE;
}
.codeArea #content ol, .codeArea #gutter ol {
 list-style-position: inside;
 padding-left: 10px;
 margin: 0px;
}
.codeArea #content span, .codeArea #content ol li, .codeArea #gutter ol li {
 white-space: nowrap;
}
-->
</style>
</head>
<body>
<p> </p>
<p> </p>
<div class="codeArea"
 onscroll="document.getElementById('gutter').style.left = scrollLeft + 'px'; document.getElementById('column').style.top = scrollTop + 'px';">
  <div id="content"><pre>·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150</pre>
    <ol start="2">
     <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
        <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
        <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
        <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
    </ol>
  </div>
  <div id="gutter">
    <ol>
     <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
        <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
        <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
        <li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/><li/>
    </ol>
  </div>
  <div id="column">·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150</div>
  <div id="block"></div>
</div>
</body>
</html>

相關連結:
自改版 dp.SyntaxHighlighter 1.5.1.1

Read more...

超好用的 JavaScript 壓縮工具   [+/-]

Ticore's Blog

最近再研究一些 Blogger Plugin 發現 jQuary 等 Lib
其原始碼都是經過 Javascript Compressor 壓縮
某些情況下,壓縮率可以接近 zip 壓縮

不過使用上需要注意 JavaScript 的語法格式
最常遇到問題就是斷行與分號
下面例子看似語法 OK

var fun = function(){
  alert(new Date());
}
var a = 1;
但是壓縮後執行卻會出現問題
missing ; before statement
只要在匿名函式後面加上分號就好了
var fun = function(){
  alert(new Date());
};
var a = 1;

Read more...

AS3 E4X - XML、XMLList 物件內子節點參考指定與複製   [+/-]

Ticore's Blog

AS3 E4X XML、XMLList 物件同時具有基礎型別、複雜型別的特性
在指定與複製節點操作上需特別注意
以下便是實際容易犯錯的例子

指定 XML 子節點到外部其它節點,屬於參考行為:

var xml = <xml/>;
var node = <node/>;
xml.*[0] = node;
xml.*[1] = node;
xml.*[2] = node;

trace(xml.*[0] == node); // true
trace(xml.*[0] === node); // true

trace(xml.toXMLString());
node.* = 123;
trace(xml.toXMLString());
trace(node.toXMLString()); // <node>123</node>

trace(xml.*[0].childIndex()); // 0
trace(xml.*[1].childIndex()); // 0
trace(xml.*[2].childIndex()); // 0

// Ticore's Blog - http://ticore.blogspot.com/

XML 子節點累加運算外部其它節點,屬於複製行為:

var xml = <xml/>;
var node = <node/>;
xml.* += node;
xml.* += node;
xml.* += node;

trace(xml.*[0] == node); // true
trace(xml.*[0] === node); // false

trace(xml.toXMLString());
node.* = 123;
trace(xml.toXMLString());
trace(node.toXMLString());

trace(xml.*[0].childIndex()); // 0
trace(xml.*[1].childIndex()); // 1
trace(xml.*[2].childIndex()); // 2

// Ticore's Blog - http://ticore.blogspot.com/

XML 反覆用自身子節點插入多次,屬於參考行為:

var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
</xml>;
xml.*[1] += xml.*[0];
var xmlClone:XML = xml.copy();
xml.*[0].* = "Text";
xmlClone.*[0].* = "Text";

trace(xml.toXMLString());
trace(xml.*[0].childIndex()); // 0
trace(xml.*[1].childIndex()); // 1
trace(xml.*[2].childIndex()); // 0

trace(xmlClone.toXMLString());
trace(xmlClone.*[0].childIndex()); // 0
trace(xmlClone.*[1].childIndex()); // 1
trace(xmlClone.*[2].childIndex()); // 2

// Ticore's Blog - http://ticore.blogspot.com/
var xml:XML =
<xml>
 <node1>1</node1>
 <node2>2</node2>
</xml>;
xml.insertChildAfter(xml.*[1], xml.*[0]);
var xmlClone:XML = xml.copy();
xml.*[0].* = "Text";
xmlClone.*[0].* = "Text";

trace(xml.toXMLString());
trace(xml.*[0].childIndex()); // 0
trace(xml.*[1].childIndex()); // 1
trace(xml.*[2].childIndex()); // 0

trace(xmlClone.toXMLString());
trace(xmlClone.*[0].childIndex()); // 0
trace(xmlClone.*[1].childIndex()); // 1
trace(xmlClone.*[2].childIndex()); // 2

trace(xml.*[0] === xml.*[2]); // true
trace(xmlClone.*[0] === xmlClone.*[2]); // false

累加 XMLList 屬於參考行為:

var xml1:XMLList =
<>
 <node name="Node 1"/>
 <node name="Node 2"/>
</>;
var xml2:XMLList =
<>
 <node name="Node 3"/>
 <node name="Node 4"/>
</>;
var xml3:XMLList = <></>;

xml3 += xml1;
xml3 += xml2;

xml3[1].@name = "Node Changed";
xml3[2].@name = "Node Changed";
trace(xml3);

trace(xml3[0].childIndex()); // -1
trace(xml3[1].childIndex()); // -1
trace(xml3[2].childIndex()); // -1
trace(xml3[3].childIndex()); // -1

// Ticore's Blog - http://ticore.blogspot.com/

指定 XMLList 子節點到外部其它節點,屬於參考行為:

var xml1:XMLList =
<>
 <node name="Node 1"/>
 <node name="Node 2"/>
</>;
var xml2:XMLList =
<>
 <node name="Node 3"/>
 <node name="Node 4"/>
</>;
var xml3:XMLList = <></>;

xml3[0] = xml1[0];
xml3[1] = xml1[1];
xml3[2] = xml2[0];
xml3[3] = xml2[1];

xml3[1].@name = "Node Changed";
xml3[2].@name = "Node Changed";
trace(xml3);

trace(xml3[0].childIndex()); // -1
trace(xml3[1].childIndex()); // -1
trace(xml3[2].childIndex()); // -1
trace(xml3[3].childIndex()); // -1

XMLList 無法使用 normalize、clone XMLList 方式解除子節點參考行為:

var xml1:XMLList =
<>
 <node name="Node 1"/>
 <node name="Node 2"/>
</>;
var xml2:XMLList =
<>
 <node name="Node 3"/>
 <node name="Node 4"/>
</>;
var xml3:XMLList = <></>;

xml3 += xml1;
xml3 += xml2;

xml3.normalize();
xml3 = new XMLList(xml3);

xml3[1].@name = "Node Changed";
xml3[2].@name = "Node Changed";

trace(xml1);
trace(xml2);

trace(xml3[0].childIndex()); // -1
trace(xml3[1].childIndex()); // -1
trace(xml3[2].childIndex()); // -1
trace(xml3[3].childIndex()); // -1

// Ticore's Blog - http://ticore.blogspot.com/

由上面的例子可以看出來,有些 XML 子節點的動作屬於指定參考行為
對其中之一節點進行修改,其它節點參考也會跟著變動
這些節點 childIndex 屬性也會跟著錯亂

最好是避免在子節點操作上使用參考行為
遇到問題難以除錯
假如子節點參考已經產生,可以將整個 XML Tree copy 一次
childIndex 便會恢復正常

稍微使用 Firefox Javascript E4X 測試過
似乎也有類似的行為發生

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月14日 星期四

保留 Blogger Ajax 換頁功能,觸發自訂 JS 功能做法   [+/-]

Ticore's Blog

前篇說明如何 Disable Blogger Ajax 背景換頁功能
不過這樣時再讓瀏覽速度慢了許多
於是再想辦法既可保留 Ajax 功能又可以讓自訂 JS 功能有作用

編輯 Blogger 模板
找出 blog-posts div 區塊:

<div class='blog-posts'>
  <b:include data='top' name='status-message'/>
  <data:adStart/>
  <b:loop values='data:posts' var='post'>
    <b:if cond='data:post.dateHeader'>
      <h2 class='date-header'>
        <data:post.dateHeader/>
      </h2>
    </b:if>
    <b:include data='post' name='post'/>
    <b:if cond='data:blog.pageType == "item"'>
      <b:include data='post' name='comments'/>
    </b:if>
  </b:loop>
  <data:adEnd/>
</div>

以我的 Blog 為例子,只有用到 dp.SyntaxHighlighter 功能
在後面 div 結尾之前加上以下程式

<img onload="if(window['dp'] != null) {dp.SyntaxHighlighter.HighlightAll('code');}"
 src="http://riafiles.googlepages.com/favico.ico"></img>

img 圖片來源可以隨意修改
onload 事件內的程式就是用來處理換頁時需要執行的動作
各位可以依據需要修改

修改過後的 blog-posts 區塊:

<div class='blog-posts'>
  <b:include data='top' name='status-message'/>
  <data:adStart/>
  <b:loop values='data:posts' var='post'>
    <b:if cond='data:post.dateHeader'>
      <h2 class='date-header'>
        <data:post.dateHeader/>
      </h2>
    </b:if>
    <b:include data='post' name='post'/>
    <b:if cond='data:blog.pageType == "item"'>
      <b:include data='post' name='comments'/>
    </b:if>
  </b:loop>
  <data:adEnd/>
  <img onload="if(window['dp'] != null) {dp.SyntaxHighlighter.HighlightAll('code');}" src="http://riafiles.googlepages.com/favico.ico"></img>
</div>

後來發現可以插入 Blogger _WidgetManager 頁面更新事件的方式
Blogger Hack Tip #1 - Hacking Blogger index.html
Read more...

如何 Disable Blogger Ajax 背景換頁功能   [+/-]

Ticore's Blog

Google Blogger 可擴充彈性很高
很多人都會加上不少 javascript plugin
不過有些自訂處理文章內容的功能在遇到使用者按下 "較舊的文章" or "Older Posts" 會失效
像是隱藏全文、....功能
原因在於 Blogger 使用 Ajax 處理換頁的動作
只更新文章主體部分的 HTML 內容
這樣可以加快頁面表現速度
旦卻讓自訂的 JS 功能失效

以下則是修改 Blogger Template
讓 "較舊的文章" Ajax 功能失效,變成普通的超連結做法
在模板內找出 blog-pager-older-link 超連結位置:

<a class='blog-pager-older-link'
    expr:href='data:olderPageUrl'
    expr:id='data:widget.instanceId + "_blog-pager-older-link"'
    expr:title='data:olderPageTitle'>
    <data:olderPageTitle/>
</a>

將 expr:id='data:widget.instanceId + "_blog-pager-older-link"' 拔掉

<a class='blog-pager-older-link'
    expr:href='data:olderPageUrl'
    expr:title='data:olderPageTitle'>
    <data:olderPageTitle/>
</a>

較新的連結 作法也是類似~~
這樣就可以讓 Blogger 換頁 Ajax 功能失效~

Read more...

2007年6月13日 星期三

AS3 E4X - XML 物件比較   [+/-]

Ticore's Blog

之前在AS2、AS3 基礎型別物件一致性
稍微提到過 AS3 E4X XML 物件比較
現在再對它作其它的測試:

Attribute 先後順序不影響 XML 物件 Value 比較:
var xml1:XML = <xml attr1="Attribute 1" attr2="Attribute 2"></xml>;
var xml2:XML = <xml attr2="Attribute 2" attr1="Attribute 1"></xml>;
trace(xml1.toXMLString());
trace(xml2.toXMLString());
trace(xml1 == xml2); // true
trace(xml1 === xml2); // false
"==" 可以比較 XML 資料相等性,"===" 可以比較 XML 參考相等性:
var xml:XML = <xml></xml>;
var xmlRef:XML = xml;
var xmlClone:XML = xml.copy();
trace("xml == xmlRef : ", xml == xmlRef); // true
trace("xml === xmlRef : ", xml === xmlRef); // true
trace("xml == xmlClone : ", xml == xmlClone); // true
trace("xml === xmlClone : ", xml === xmlClone); // false
XML 設定忽略特殊節點也會影響到物件的比較:
trace(<xml><? ins ?></xml> == <xml></xml>); // true
trace(<xml><!-- comm --></xml> == <xml></xml>); // true
trace(<xml> </xml> == <xml></xml>); // true
XML.ignoreWhitespace = false;
XML.ignoreComments = false;
XML.ignoreProcessingInstructions = false;
trace(<xml><? ins ?></xml> == <xml></xml>); // false
trace(<xml><!-- comm --></xml> == <xml></xml>); // false
trace(<xml> </xml> == <xml></xml>); // false
檢查 XML 下有無指定的 Value 物件:
var xml:XML =
<xml>
 <node/>
 <node/>
 <node/>
</xml>;
trace(xml.contains(<node/>)); // false
trace(xml.contains(new XML(<node/>))); // false
trace(xml.*.contains(<node/>)); // true
trace(xml.*.contains(new XML(<node/>))); // true

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

AS3 E4X - 相關類別與物件建立   [+/-]

Ticore's Blog

ActionScript 3.0 中與 E4X (ECMAScript for XML) 相關的內建類別有:
XMLXMLListNamespaceQName
以及兩個 global function:
XMLXMLList

建立 AS3 XML 物件

  • 直接宣告 XML 物件:
    var xml:XML = <xml></xml>;
    trace(xml.toXMLString());
    
  • 建構式解析字串建立:
    var xml:XML = new XML("<xml></xml>");
    trace("xml : " + xml.toXMLString());
    
  • 全域函式解析字串建立:
    var xml:XML = XML("<xml></xml>");
    trace("xml : " + xml.toXMLString());
    
  • 由全域函式傳入其它 XML 得到參考:
    var xml1:XML = <xml></xml>;
    var xml2:XML = XML(xml1);
    xml1.* += <node />;
    trace("xml1 : " + xml1.toXMLString());
    trace("xml2 : " + xml2.toXMLString());
    
  • 從其它 XML 物件複製建立:
    var xml1:XML = <xml></xml>;
    var xml2:XML = new XML(xml1);
    xml1.* += <node />;
    trace("xml1 : " + xml1.toXMLString());
    trace("xml2 : " + xml2.toXMLString());
    
    var xml1:XML = <xml></xml>;
    var xml2:XML = xml1.copy();
    xml1.* += <node />;
    trace("xml1 : " + xml1.toXMLString());
    trace("xml2 : " + xml2.toXMLString());
    
  • 由 XML Template 建立:
    var nodeName:String = "xml";
    var attrName:String = "attr";
    var attrValue:String = "Attribute";
    var txt:String = "Text Node";
    var xml:XML = <{nodeName} {attrName}={attrValue}>{txt}</{nodeName}>;
    trace(xml.toXMLString());
    
建立 AS3 XMLList 物件
  • 由全域函式解析字串建立:
    var xmlList:XMLList = XMLList("<xml>text1</xml><xml>text2</xml>");
    trace(xmlList[0]);
    trace(xmlList[1]);
    trace(xmlList.toXMLString());
    
  • 由全域函式傳入其它 XMLList 得到參考:
    var xml:XML =
    <xml>
     <node/>
     <node/>
     <node/>
    </xml>;
    var xmlList:XMLList = XMLList(xml.node);
    xml.node[0].* = "text";
    trace(xml.*.toXMLString());
    trace(xmlList.toXMLString());
    
  • 使用空白建構式建立:
    var xmlList:XMLList = new XMLList();
    xmlList[0] = <xml />;
    xmlList[1] = "text";
    xmlList[2] = <node />;
    trace(xmlList.toXMLString());
    
  • 建構式傳入其它 XMLList 參數得到參考:
    var xml:XML =
    <xml>
     <node/>
     <node/>
     <node/>
    </xml>;
    var xmlList:XMLList = new XMLList(xml.node);
    xml.node[0].* = "text";
    trace(xml.*.toXMLString());
    trace(xmlList.toXMLString());
    
  • 建構式解析字串建立:
    var xmlList:XMLList = new XMLList("<xml>text1</xml><xml>text2</xml>");
    trace(xmlList[0]);
    trace(xmlList[1]);
    trace(xmlList.toXMLString());
    
  • 由 XML 物件篩選得到參考:
    var xml:XML =
    <xml>
     <node/>
     <node/>
     <node/>
    </xml>;
    var xmlList:XMLList = xml.node;
    trace(xmlList.toXMLString());
    

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS2、AS3 基礎型別物件一致性
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月12日 星期二

AS2、AS3 基礎型別物件一致性   [+/-]

Ticore's Blog

之前測試過ActionScript 3.0 beta 1 物件比較
不過漏掉了 === 比較運算子
這次 Flash CS3 正式版也出了
就針對基礎型別物件分別以 AS2、AS3 比較測試
String Compare in AS2:

var a:String = "str";
var b:String = new String(a);
var c:String = new String(b);

trace(a == b); // true
trace(b == c); // false
trace(c == a); // true

trace(a === b); // false
trace(b === c); // false
trace(c === a); // false

trace(a + "" == b); // true
trace(b + "" == c); // true
trace(c + "" == a); // true
trace(a == b + ""); // true
trace(b == c + ""); // true
trace(c == a + ""); // true

trace(a + "" === b); // false
trace(b + "" === c); // false
trace(c + "" === a); // true
trace(a === b + ""); // true
trace(b === c + ""); // false
trace(c === a + ""); // false

trace(String(a) == b); // true
trace(String(b) == c); // true
trace(String(c) == a); // true
trace(a == String(b)); // true
trace(b == String(c)); // true
trace(c == String(a)); // true

trace(String(a) === b); // false
trace(String(b) === c); // false
trace(String(c) === a); // true
trace(a === String(b)); // true
trace(b === String(c)); // false
trace(c === String(a)); // false

Number Compare in AS2:

var a:Number = 1.1;
var b:Number = new Number(a);
var c:Number = new Number(b);

trace(a == b); // true
trace(b == c); // false
trace(c == a); // true

trace(a === b); // false
trace(b === c); // false
trace(c === a); // false

trace(a + 0 == b); // true
trace(b + 0 == c); // true
trace(c + 0 == a); // true
trace(a == b + 0); // true
trace(b == c + 0); // true
trace(c == a + 0); // true

trace(a + 0 === b); // false
trace(b + 0 === c); // false
trace(c + 0 === a); // true
trace(a === b + 0); // true
trace(b === c + 0); // false
trace(c === a + 0); // false

trace(Number(a) == b); // true
trace(Number(b) == c); // true
trace(Number(c) == a); // true
trace(a == Number(b)); // true
trace(b == Number(c)); // true
trace(c == Number(a)); // true

trace(Number(a) === b); // false
trace(Number(b) === c); // false
trace(Number(c) === a); // true
trace(a === Number(b)); // true
trace(b === Number(c)); // false
trace(c === Number(a)); // false

Boolean Compare in AS2:

var a:Boolean = true;
var b:Boolean = Boolean(a);
var c:Boolean = new Boolean(b);

trace(a == b); // true
trace(b == c); // true
trace(c == a); // true

trace(a === b); // true
trace(b === c); // false
trace(c === a); // false

trace(Boolean(a) == b); // true
trace(Boolean(b) == c); // true
trace(Boolean(c) == a); // true
trace(a == Boolean(b)); // true
trace(b == Boolean(c)); // true
trace(c == Boolean(a)); // true

trace(Boolean(a) === b); // true
trace(Boolean(b) === c); // false
trace(Boolean(c) === a); // true
trace(a === Boolean(b)); // true
trace(b === Boolean(c)); // true
trace(c === Boolean(a)); // false

String、Number、Boolean 在 AS2 的比較結果實在有點詭異
平常還是少用 new 建立 String、Number、Boolean 比較好
假如都拿到 AS3 測試,上述所有的結果都會變成 true
AS3 其它的基礎型別 int、uint.. 就不另外測試了
看起來在 AS3 已經把 String、Number、Boolean.. 比較行為統一簡化了

不過 AS3 新增的 E4X XML 物件
看起來像是 Complex Object,但是卻又可以用 == 比較資料相等性
還是要好好測試一下

XML Compare in AS3:

var a:XML = <xml/>;
var b:XML = XML(a);
var c:XML = new XML(b);

trace(a == b); // true
trace(b == c); // true
trace(c == a); // true

trace(a === b); // true
trace(b === c); // false
trace(c === a); // false

trace(XML(a) == b); // true
trace(XML(b) == c); // true
trace(XML(c) == a); // true
trace(a == XML(b)); // true
trace(b == XML(c)); // true
trace(c == XML(a)); // true

trace(XML(a) === b); // true
trace(XML(b) === c); // false
trace(XML(c) === a); // false
trace(a === XML(b)); // true
trace(b === XML(c)); // false
trace(c === XML(a)); // false

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
原來 Firefox 1.5 就已經開始支援 E4X

Read more...

2007年6月11日 星期一

Flash Player 9 Update 3 Beta 新功能   [+/-]

Ticore's Blog

Flash Player 9 又出更新 Beta 版了
(Version 9.0.60.120)
頻率也太高了一些
仗著普及速度高的優勢嗎?

Flash Player 9 Update

這次的新功能有:
1. 全螢幕模式影片撥放增強:有提到硬體加速功能,未來可能會支援 3D 加速卡嗎?
2. Flash Player Cache:提供獨立於瀏覽器之外的快取功能,只有 Adobe 簽章過的元件可以被 Cache,像是 Flex 就是第一個

相關連結: Flash Player Update 3 Beta 1

Read more...

2007年6月8日 星期五

原來 Firefox 1.5 就已經開始支援 E4X   [+/-]

Ticore's Blog

E4X 是 ActionScript 3.0 重要新特色之一
當大家測試這新功能之際
沒注意到,早在 Firefox 1.5 就已經支援 E4X
支援的速度很快,可是討論與使用的人卻是相當的少
而 Flash Player 9 只要再過一段時間,普及率就會上來
屆時,新功能便可應用於專案上
反觀 dHTML 技術新規格,似乎再過個三年,都沒辦法確保大部分用戶的瀏覽器支援

JavaScript 1.6 新鮮事 - MDC

相關連結:
AS3 - Inline 宣告 XMLList 物件方式
Flash CS3 jsfl 也支援 E4X, RegExp
AS3 E4X 互補方案 XPath
AS3 E4X - QName 相關操作
AS3 利用 QName 快速存取 Namespace Member
AS3 E4X - XML 節點包覆
AS3 E4X 資料取出與計算
AS3 E4X - XML 節點交換
AS3 E4X - 插入 XML 節點
AS3 E4X - 刪除 XML 節點
AS3 E4X Tip - 你拿到的是 XML or XMLList?
AS3 E4X 技巧 - 替 XML 添加 prototype fnuction
AS3 E4X - XML Attribute 相關操作
用 @* 指定 Attributes 造成 Flash Player 9 Crash
AS3 E4X - XML、XMLList 物件內子節點參考指定與複製
AS3 E4X - XML 物件比較
AS3 E4X - 相關類別與物件建立
AS2、AS3 基礎型別物件一致性

Read more...

2007年6月6日 星期三

Flash CS3 - AS3 又一影格程式問題   [+/-]

Ticore's Blog

之前已經有幾個 Flash CS3 AS3 影格程式的問題
(Flash CS3 - AS3 影格程式重複觸發問題一行 AS3 程式讓 Flash Player 9 死機)

現在又來一個
直接在影格上輸入以下程式:

var Obj:Object = {};
Obj.test1 = function():void{
 var i:Number;
};
Obj.test2 = function():void{
 var i:Number;
};

測試影片,就會遇到

Compiler Error: 1151: A conflict exists with definition i in namespace internal. var i:Number;

看起來 ActionScript 3.0 真的很不適合大量使用 Frame Script 啊~

Read more...

2007年6月5日 星期二

SWF9 傳遞參數給 SWF8 的方式   [+/-]

Ticore's Blog

一般嵌入網頁中的 SWF 可以利用 FlashVars 或是 URL GET 傳遞參數
(URL GET 方式會造成瀏覽器快取失效,不建議使用)

而 SWF Load SWF 時剩下 URL GET 方式以及 MovieClipLoader or Loader 相關事件處理機制可用
若是 SWF9 Load SWF8 則是連事件處理都難以使用
(SWF9 與 SWF8 之間的溝通方式)

此時改用 URL 後面附加 # 參數似乎不錯
可以避免掉 URL GET 造成快取失效的問題

ActionScript 2.0 Parse Anchor Parameter
var paramStr:String = _url.split("#")[1];
paramStr = paramStr == null ? "" : paramStr;
var paramObj:LoadVars = new LoadVars();
paramObj.decode(paramStr);
for (var i in paramObj) {
 txt.text += i + " : " + paramObj[i] + "\n";
}

 

ActionScript 3.0 Pass Parameter by Anchor
package {
 import flash.display.*;
 import flash.net.*;
 public class main extends MovieClip {
  
  private var loader1:Loader;
  private var loader2:Loader;
  
  public function main() {
   stage.scaleMode = StageScaleMode.NO_SCALE;
   init();
  }
  public function init():void {
   loader1 = new Loader();
   loader2 = new Loader();
   loader2.y = 100;
   loader1.load(new URLRequest("swf8.swf#var1=11&var2=22"));
   loader2.load(new URLRequest("swf8.swf#var1=22&var2=11"));
   this.addChild(loader1);
   this.addChild(loader2);
  }
 }
}

實際放到 HTTP Server 上進行測試
可以發現利用錨點傳遞參數不會造成 SWF 檔案快取失效

Read more...