本教程中你将学习下面的内容:
1.事件处理机制.
2.创建类库.
3.使用 回调函数.
3.1.示例: CFEventClass 类(简单的示例).
3.2.示例: CFTimer 类(定时器).
4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类).
4.1.示例: AsBEventClass 类(简单的示例).
4.2.示例: AsBTimer 类(定时器).
5.使用 addEventListener 方法(EventDispatcher 类).
5.1.示例: EDEventClass 类(简单的示例).
5.2.示例: EDTimer 类(定时器).
6.建立强大的事件处理机制.
6.1.创建 CFDelegate 类(修改 Delegate 类).
6.2.创建 CFEventDispatcher 类(修改 EventDispatcher 类).
6.3.创建 Event 类(事件基类,继承 Object 类).
6.4.创建 IOErrorEvent 类(错误事件类,继承 Event 类).
6.5.创建 HTTPStatusEvent 类(http状态事件类,继承 Event 类).
6.6.示例: EventClass 类(简单的示例).
6.7.示例: Timer 类(定时器,功能跟 AS3 中的 Timer 类一样).
7.小结.
源文件(LRC 和 CFSound 类也在这):Flash Class Library.rar
[1.事件处理机制]
AS2 的事件处理机制并不完美.形态多样.不易于管理.在这里可以解决此问题的一半.本文会先了解和使用
AS2 中基本的事件处理机制.然后建立强大的事件处理机制.来方便管理自己的程序.下面讲解.
形态多样的事件处理机制(后面会详细的讲解):
1.回调函数.(如 onLoad, onHTTPStatus 等)
2.使用 addListener 方法. (如 onLoadStart, onLoadInit 等)
3.使用 addEventListener 方法. (如 click, change 等)
它们的作用域和形态(代码):
作用域是指标识符(如常量、数据类型、变量或例程)在程序内可被引用的范围.
1.this 指向触发此事件的对象
object.onLoad = function()
{
trace(this); //输出: object
}
2.this 指向侦听器对象
var listenerObject:Object = {};
listenerObject.onLoadStart = function()
{
trace(this); //输出: listenerObject
}
broadcasterObject.addListener(listenerObject);
3.使用侦听器对象:this 指向侦听器对象
var listenerObject:Object = {};
listenerObject.click = function(evt:Object)
{
trace(this); //输出: listenerObject
}
broadcasterObject.addEventListener("click", listenerObject);
使用函数:this 指向触发此事件的对象
function clickHandler(evt:Object):Void
{
trace(this); //输出: broadcasterObject
}
broadcasterObject.addEventListener("click", clickHandler);
有时我们需要更改它们的作用域怎么办?
想要改变它们的作用域,需使用 Delegate 类的 create 方法.
此类的全路径: mx.utils.Delegate;
用法: Delegate.create(要运行函数的范围, 函数);
例:
1.this 指向 _level0
import mx.utile.Delegate;
object.onLoad = Delegate.create(this, _onLoad);
function _onLoad():Void
{
trace(this); //输出: _level0
}
2.this 指向 _level0
import mx.utile.Delegate;
var listenerObject:Object = {};
listenerObject.onLoadStart = Delegate.create(this, loadStart);
function loadStart():Void
{
trace(this); //输出: _level0
}
broadcasterObject.addListener(listenerObject);
3.
使用侦听器对象:this 指向 _level0
import mx.utile.Delegate;
var listenerObject:Object = {};
listenerObject.click = Delegate.create(this, clickHandler);
function clickHandler(evt:Object)
{
trace(this); //输出: _level0
}
broadcasterObject.addEventListener("click", listenerObject);
使用函数:this 指向 _level0
function clickHandler(evt:Object):Void
{
trace(this); //输出: _level0
}
broadcasterObject.addEventListener("click", Delegate.create(this, clickHandler));
事件对象:
它包含两个基本属性:
type:String 事件名.
target:Object 事件源.此属性可以不指定,默认为事件源(调用dispatchEvent方法的对象).
此对象传递给 EventDispatcher 类的 dispatchEvent 方法并作为参数传递到侦听器.
例:
//发送事件.
dispatchEvent({type:"click", target:this});
//事件处理函数.
function clickHandler(evt:Object):Void
{
trace([evt.type, evt.target]);
}
//添加事件侦听器.
addEventListener("click", clickHandler);
下一节讲:[2.创建类库]
在开始下面的教程之前.先要创建类库.在硬盘中创建如图结构的文件目录:

Classes 目录是用来存放类文档.
Example 目录是用来存放示例文档.
创建好后还需要在 Flash 中添加类路径:
Flash 8: 编辑-->首选参数-->ActionScript-->ActionScript 2.0 设置-->添加(+)-->浏览到 Flash Class Library/Classes 目录.

Flash CS3: Edit-->Preferences-->ActionScript-->ActionScript 2.0 Settings-->Add New Path(+)-->Browse To Flash Class Library/Classes 目录.
ActionScript 3.0 也要添加(在后续文章中会用到).

下一节讲: [3.使用 回调函数]
[3.使用 回调函数]
回调函数也可以说是匿名函数,先看下面的代码:
var myXML:XML = new XML();
myXML.load("xml.xml");
myXML.onLoad = function(success:Boolean)
{
trace(success);
}
XML.onLoad 是一个回调函数.将匿名函数与特定的事件关联,以创建回调函数.函数将在特定事件发生后调用回调函数.
在自定义类中怎么做呢?看下面的示例.
[3.1.示例: CFEventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/CFEvent/CFEventClass.as
Example/AS2/events/CFEvent/CFEventExample.as
Example/AS2/events/CFEvent/CFEventExample.xml
Example/AS2/events/CFEvent/CFEventExample.fla
主类:
打开 CFEventClass.as 文档,输入下面的代码:
import mx.utils.Delegate;
//----------------------------------------
class CFEventClass
{
//----------------------------------------
public var tXML:XML;
//定义事件函数.
public var complete:Function;
//----------------------------------------
public function CFEventClass(url:String)
{
this.tXML = new XML();
this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
this.tXML.load(url);
}
private function XMLonLoad(success:Boolean):Void
{
if (success) {
//执行事件函数.
this.complete();
}
}
//----------------------------------------
}
保存文档,这样我们就创建了一个名为 CFEventClass 的类,拥有一个事件,一个属性,此事件在 XML 文档成功加载后发生.
示例类:
打开 CFEventExample.as 文档,输入下面的代码:
import CFEventClass;
//----------------------------------------
class CFEventExample
{
public function CFEventExample()
{
var ee:CFEventClass = new CFEventClass("CFEventExample.xml");
ee.complete = this.complete;
}
private function complete():Void
{
trace("complete");
}
}
保存文档.
在示例类中我们创建主类的一个实例.来加载 CFEventExample.xml 文档.然后使用自定义函数与 complete 事件关联.
如果要移除事件,请使用下面的方法:
ee.complete = undefined
//或
ee.complete = null;
//或
delete ee.complete;
要加载的 XML 文档:
打开 CFEventExample.xml 文档,随便输入一些内容便可.测试用.
示例 fla 文档:
打开 CFEventExample.fla 文档.将"图层 1"重命名为 Actions.并在第一帧中输入下面的代码:
new CFEventExample();
保存文档.
测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容
complete
如需给事件传递参数,在执行事件函数时如下添加参数:
this.complete(参数1, 参数2, 参数N);
在调用事件时:
private function complete(参数1, 参数2, 参数N)
{
trace([参数1, 参数2, 参数N]);
}
下面再看一个示例:
[3.2.示例: CFTimer 类(定时器)]
此示例文档详细:
Classes/AS2/utils/CFTimer.as
Example/AS2/utils/CFTimer/CFTimerExample.as
Example/AS2/utils/CFTimer/CFTimerExample.fla
主类:
打开 CFTimer.as 文档,输入下面的代码:
import mx.utils.Delegate;
//----------------------------------------
class AS2.utils.CFTimer
{
//----------------------------------------
private var _timerID:Number;
private var _delay:Number;
private var _repeatCount:Number;
private var _currentCount:Number = 0;
private var _running:Boolean;
//----------------------------------------
public var timer:Function;
public var timerComplete:Function;
//----------------------------------------
/*
@parameter delay: 延迟,单位毫秒.
@parameter repeatCount: 重复的次数.默认为Infinity(正无穷大);
*/
public function CFTimer(delay:Number, repeatCount:Number)
{
if (isNaN(delay)) {
return;
}
if (isNaN(repeatCount)) {
repeatCount = Infinity;
}
this._delay = delay;
this._repeatCount = repeatCount;
}
//----------------------------------------
public function reset():Void
{
this._currentCount = 0;
this.stop();
}
public function start():Void
{
this._timerID = setInterval(CFDelegate.create(this, this.startTimer), this._delay);
this._running = true;
}
public function stop():Void
{
clearInterval(this._timerID);
this._running = false;
}
public function toString():String
{
return "[CFTimer]";
}
//----------------------------------------
private function startTimer():Void
{
this._currentCount++;
this.timer(this._currentCount);
if (this._currentCount == this._repeatCount) {
this.reset();
this.timerComplete();
}
}
//----------------------------------------
public function get delay():Number
{
return this._delay;
}
public function set delay(d:Number):Void
{
this._delay = d;
}
public function get repeatCount():Number
{
return this._repeatCount;
}
public function set repeatCount(r:Number):Void
{
this._repeatCount = r;
}
public function get currentCount():Number
{
return this._currentCount;
}
public function get running():Boolean
{
return this._running;
}
//----------------------------------------
}
保存文档.
此类的详细信息:
构造函数:
public CFTimer(delay:Number, repeatCount:Number)
参数:
delay:Number ---延迟,单位毫秒.
repeatCount:Number ---重复次数.默认为 Infinity(正无穷大);
方法:
public reset():Void ---停止定时.并复位 currentCount .
public start():Void ---开始计时.
public stop():Void ---停止定时.
public toString():String ---返回类名称"[CFTimer]".
属性:
public delay:Number ---延迟,单位毫秒.
public repeatCount:Number ---重复的次数.默认值为 Infinity(正无穷大);
public currentCount:Number [只读] ---当前的次数.当开始计时,此值会递增,直到等于 repeatCount.
public running:Boolean [只读] ---定时器目前的状态,true 表示正在运行, false 表示已停止.
事件:
timer = function(currentCount:Number){} ---每当时间间隔到达 delay 时调用.
timerComplete = function(){} ---当 currentCount 等于 repeatCount 时调用.
示例类:
打开 CFTimerExample.as 文档.输入下面的代码:
import AS2.utils.CFTimer;
//----------------------------------------
class CFTimerExample
{
//----------------------------------------
public function CFTimerExample()
{
var te:CFTimer = new CFTimer(1000, 5);
te.timer = this.timer;
te.timerComplete = this.timerComplete;
te.start();
}
private function timer(currentCount:Number):Void
{
trace("timer: " + currentCount);
}
private function timerComplete():Void
{
trace("timerComplete: ");
}
//----------------------------------------
}
保存文档.
这里我们创建 CFTimer 类的一个实例, 时间间隔为 1000 毫秒,重复执行 5 次.然后实现 timer 和 timerComplete 事件.
示例 fla 文档:
打开 CFTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:
new CFTimerExample();
测试 Flash 文档.输出面板会陆续显示以下的内容:
timer: 1
timer: 2
timer: 3
timer: 4
timer: 5
timerComplete:
下一节讲: [4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类)]
[4.使用 addListener 方法(AsBroadcaster / BroadcasterMX 类)]
在 MovieClipLoader 和 Tween 等类中都用到了 addListener 方法来注册侦听.
我们该怎么用呢? Macromedia 为我们提供了如下二个类:
AsBroadcaster 属于系统类.
BroadcasterMX 属于自定义类.类路径: mx.transitions.BroadcasterMX
这两个类的很相似.它们都是提供事件通知和侦听器管理功能.
但 AsBroadcaster 类是系统内置的.执行效率会比 BroadcasterMX 类快很多.所以这里我们就用 AsBroadcaster
类来讲解.
此类详细:
public addListener(listenerObj:Object):Boolean ---注册侦听器.
public broadcastMessage(eventName:String):Void ---广播消息/发送事件.
public static initialize(obj:Object):Void ---将事件通知和侦听器管理功能添加到给指定的对象
public removeListener(listenerObj:Object):Boolean ---移除侦听器.
public _listeners:Array [只读] ---对已注册侦听器对象的引用.
该怎么用呢? 看下面的示例:
[4.1.示例: AsBEventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/AsBEvent/AsBEventClass.as
Example/AS2/events/AsBEvent/AsBEventExample.as
Example/AS2/events/AsBEvent/AsBEventExample.xml
Example/AS2/events/AsBEvent/AsBEventExample.fla
主类:
打开 CFEventClass.as 文档,输入下面的代码:
import mx.utils.Delegate;
//----------------------------------------
class AsBEventClass extends AsBroadcaster
{
//----------------------------------------
public var tXML:XML;
//----------------------------------------
public function AsBEventClass(url:String)
{
AsBroadcaster.initialize(AsBEventClass.prototype);
this.tXML = new XML();
this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
this.tXML.load(url);
}
private function XMLonLoad(success:Boolean):Void
{
if (success) {
this.broadcastMessage("complete");
}
}
//----------------------------------------
}
保存文档.
这里首先继承 AsBroadcaster 类.然后在构造函数中使用
AsBroadcaster.initialize(AsBEventClass.prototype);
来获取事件通知和侦听器管理功能.最后使用
this.broadcastMessage("complete");
来广播消息或发送事件.
当然你也可以选择不继承它,但需要在类中添加下面的方法:
public var addListener:Function;
public var removeListener:Function;
private var broadcastMessage:Function;
示例类:
打开 CFTimerExample.as 文档.输入下面的代码:
import AsBEventClass;
//----------------------------------------
class AsBEventExample
{
public function AsBEventExample()
{
var ee:AsBEventClass = new AsBEventClass("AsBEventExample.xml");
ee.addListener(this);
}
private function complete():Void
{
trace("complete");
}
}
保存文档.
在示例类中我们创建主类的一个实例.来加载 AsBEventExample.xml 文档.然后添加侦听器.
如果要移除侦听器,请使用下面的方法:
ee.removeListener(this);
要加载的 XML 文档:
打开 AsBEventExample.xml 文档,随便输入一些内容便可.测试用.
示例 fla 文档:
打开 AsBEventExample.fla 文档.将"图层 1"重命名为 Actions.并在第一帧中输入下面的代码:
new AsBEventExample();
保存文档.
测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容
complete
如需给事件传递参数,在发送事件时如下添加参数:
this.broadcastMessage("complete", 参数1, 参数2, 参数N);
在调用事件时:
private function complete(参数1, 参数2, 参数N)
{
trace([参数1, 参数2, 参数N]);
}
下面再看一个示例:
[4.2.示例: AsBTimer 类(定时器)]
此示例文档详细:
Classes/AS2/utils/AsBTimer.as
Example/AS2/utils/AsBTimer/AsBTimerExample.as
Example/AS2/utils/AsBTimer/AsBTimerExample.fla
主类:
打开 AsBTimer.as 文档,输入下面的代码:
import AS2.utils.CFDelegate;
//----------------------------------------
class AS2.utils.AsBTimer extends AsBroadcaster
{
//----------------------------------------
private var _timerID:Number;
private var _delay:Number;
private var _repeatCount:Number;
private var _currentCount:Number = 0;
private var _running:Boolean;
//----------------------------------------
/*
@parameter delay: 延迟,单位毫秒.
@parameter repeatCount: 重复次数.默认为Infinity(正无穷大);
*/
public function AsBTimer(delay:Number, repeatCount:Number)
{
AsBroadcaster.initialize(AsBTimer.prototype);
if (isNaN(delay)) {
return;
}
if (isNaN(repeatCount)) {
repeatCount = Infinity;
}
this._delay = delay;
this._repeatCount = repeatCount;
}
//----------------------------------------
public function reset():Void
{
this._currentCount = 0;
this.stop();
}
public function start():Void
{
this._timerID = setInterval(CFDelegate.create(this, this.startTimer), this._delay);
this._running = true;
}
public function stop():Void
{
clearInterval(this._timerID);
this._running = false;
}
public function toString():String
{
return "[AsBTimer]";
}
//----------------------------------------
private function startTimer():Void
{
this._currentCount++;
this.broadcastMessage("timer", this._currentCount);
if (this._currentCount == this._repeatCount) {
this.reset();
this.broadcastMessage("timerComplete");
}
}
//----------------------------------------
public function get delay():Number
{
return this._delay;
}
public function set delay(d:Number):Void
{
this._delay = d;
}
public function get repeatCount():Number
{
return this._repeatCount;
}
public function set repeatCount(r:Number):Void
{
this._repeatCount = r;
}
public function get currentCount():Number
{
return this._currentCount;
}
public function get running():Boolean
{
return this._running;
}
//----------------------------------------
}
因此类详细前面已讲,功能一样,只是事件处理机制不同而已.这里就不再啰嗦.
示例类:
打开 AsBTimerExample.as 文档.输入下面的代码:
import AS2.utils.AsBTimer;
//----------------------------------------
class AsBTimerExample
{
//----------------------------------------
public function AsBTimerExample()
{
var te:AsBTimer = new AsBTimer(1000, 5);
te.addListener(this);
te.start();
}
private function timer(currentCount:Number):Void
{
trace("timer: " + currentCount);
}
private function timerComplete():Void
{
trace("timerComplete: ");
}
//----------------------------------------
}
保存文档.
示例 fla 文档:
打开 AsBTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:
new AsBTimerExample();
测试 Flash 文档.输出面板会陆续显示以下的内容:
timer: 1
timer: 2
timer: 3
timer: 4
timer: 5
timerComplete:
下一节讲:[5.使用 addEventListener 方法(EventDispatcher 类)]
[5.使用 addEventListener 方法(EventDispatcher 类)]
打瞌睡了吧? 貌似有口水流下来了.呵.本人文字表达能力不是很好(好像是没吃多少书).让大家见笑了.其实学编程
是比较闷的.不只是闷,还有很多很多,但既然选择了,这些就只是学习途中的坎,需要我们跨过去.就像是你选择走哪
条路一样,既然选择了,就必需是要走的.但这路不只是你一个人走,人多了就会有竞争,我们不能总走在别人后面.所
以需要加快脚步走在前面,让后面的人去追.但有时也会在不知不觉中走弯路,我一样也会,所以在本文中如果你看到
有不正确的,希望你能指正,谢谢.此文的目的是想让大家在这条路上能走快点.你很啰嗦呀....呵.题外话就说到这.
下面继续.
这一节讲 EventDispatcher 类.此类也是提供事件通知和侦听器管理功能的,但比前面讲的功能会强一些.在 AS2
中,此类用于组件的事件处理机制中.因 Macromedia 没有过多的讲解此类.很少人将它用于自定义类中.本人在研究
mx包下的类时才知道此类的用法.
首先看看在组件中如何使用:
1.
function clickHandler(evt:Object):Void
{
trace("click");
]
button.addEventListener("click", clickHandler);
2.
function click(evt:Object):Void
{
trace("click");
]
button.addEventListener("click", this);
3.
function handleEvent(evt:Object):Void
{
trace("click");
]
button.addEventListener("click", this);
4.
button.clickHandler = function(evt:Object)
{
trace("click");
}
这几种写法其效果都是一样的.都是侦听 button 实例的 click 事件.
下面来了解此类详细:
public addEventListener(eventName:String, 侦听器对象或函数):Void ---添加事件侦听器
public removeEventListener(eventName:String, 侦听器对象或函数):Void ---移除事件侦听器
public dispatchEvent(eventObj:Object):Void object:Object):Void
帮助文档中没有讲解 initialize 方法.此方法的功能同 AsBroadcaster 类的 initialize 方法一样.
该怎么用呢? 看下面的示例:
[5.1.示例: EDEventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/EDEvent/EDEventClass.as
Example/AS2/events/EDEvent/EDEventExample.as
Example/AS2/events/EDEvent/EDEventExample.xml
Example/AS2/events/EDEvent/EDEventExample.fla
主类:
打开 EDEventClass.as 文档,输入下面的代码:
import mx.utils.Delegate;
import mx.events.EventDispatcher;
//----------------------------------------
class EDEventClass extends EventDispatcher
{
//----------------------------------------
public var tXML:XML;
//----------------------------------------
public function EDEventClass(url:String)
{
this.tXML = new XML();
this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
this.tXML.load(url);
}
private function XMLonLoad(success:Boolean):Void
{
if (success) {
this.dispatchEvent({type:"complete"});
}
}
//----------------------------------------
}
如果不继承 EventDispatcher 类.请将代码改成如下:
import mx.utils.Delegate;
import mx.events.EventDispatcher;
//----------------------------------------
class EDEventClass
{
//----------------------------------------
//不继承需添加这三个方法.
public var addEventListener:Function;
public var removeEventListener:Function;
private var dispatchEvent:Function;
//----------------------------------------
public var tXML:XML;
//----------------------------------------
public function EDEventClass(url:String)
{
//还有使用 initialize 静态方法.
EventDispatcher.initialize(this);
this.tXML = new XML();
this.tXML.onLoad = Delegate.create(this, this.XMLonLoad);
this.tXML.load(url);
}
private function XMLonLoad(success:Boolean):Void
{
if (success) {
this.dispatchEvent({type:"complete"});
}
}
//----------------------------------------
}
保存文档.
这里首导入 EventDispatcher 类,你可以选择继承或不继承此类.上面的代码一个是继承,一个是不继承.区别
也很容易看出来.这里就不讲了.
示例类:
打开 EDEventExample.as 文档,输入下面的代码:
import EDEventClass;
//----------------------------------------
class EDEventExample
{
public function EDEventExample()
{
var ee:EDEventClass = new EDEventClass("EDEventExample.xml");
ee.addEventListener("complete", this);
}
private function complete(evt:Object):Void
{
trace("complete");
}
}
保存文档.
在示例类中我们创建主类的一个实例.来加载 EDEventExample.xml 文档.然后添加侦听器.
如果要移除事件侦听器,请使用下面的方法:
ee.removeEventListener("complete", this);
要加载的 XML 文档:
打开 EDEventExample.xml 文档,随便输入一些内容便可.测试用.
示例 fla 文档:
打开 EDEventExample.fla 文档.将"图层 1"重命名为 Actions.并在第一帧中输入下面的代码:
new EDEventExample();
保存文档.
测试 Flash 文档.在 XML 文档成功加载后会在输出面板中显示以下内容
complete
如需给事件传递参数,在发送事件时将参数添加事件对象(请看:1.事件处理机制)中,如下添加:
this.dispatchEvent({type:"complete", 参数1:"参数1", 参数2:"参数2", 参数N:"参数N");
在调用事件时:
private function complete(evt:Object)
{
trace([evt.type, evt.target, evt.参数1, evt.参数2, evt.参数N]);
}
下面再看一个示例:
[5.2.示例: EDTimer 类(定时器)]
此示例文档详细:
Classes/AS2/utils/EDTimer.as
Example/AS2/utils/EDTimer/EDTimerExample.as
Example/AS2/utils/EDTimer/EDTimerExample.fla
主类:
打开 EDTimer.as 类,输入下面的代码(当不急时,应多打代码(有利于巩固知识).不应 copy/paste):
import mx.utils.Delegate;
import mx.events.EventDispatcher;
//------------------------------
class AS2.utils.EDTimer extends EventDispatcher
{
//------------------------------
private var _timerID:Number;
private var _delay:Number;
private var _repeatCount:Number;
private var _currentCount:Number = 0;
private var _running:Boolean;
//------------------------------
/*
@parameter delay: 延迟,单位毫秒.
@parameter repeatCount: 重复次数.默认为Infinity(正无穷大);
*/
public function EDTimer(delay:Number, repeatCount:Number)
{
if (isNaN(delay)) {
return;
}
if (isNaN(repeatCount)) {
repeatCount = Infinity;
}
this._delay = delay;
this._repeatCount = repeatCount;
}
//------------------------------
public function reset():Void
{
this._currentCount = 0;
this.stop();
}
public function start():Void
{
this._timerID = setInterval(Delegate.create(this, this.startTimer), this._delay);
this._running = true;
}
public function stop():Void
{
clearInterval(this._timerID);
this._running = false;
}
public function toString():String
{
return "[EDTimer]";
}
//----------------------------------------
private function startTimer():Void
{
this._currentCount++;
this.dispatchEvent({type:"timer", currentCount:this._currentCount});
if (this._currentCount == this._repeatCount) {
this.reset();
this.dispatchEvent({type:"timerComplete"});
}
}
//------------------------------
public function get delay():Number
{
return this._delay;
}
public function set delay(d:Number):Void
{
this._delay = d;
}
public function get repeatCount():Number
{
return this._repeatCount;
}
public function set repeatCount(r:Number):Void
{
this._repeatCount = r;
}
public function get currentCount():Number
{
return this._currentCount;
}
public function get running():Boolean
{
return this._running;
}
//------------------------------
}
因此类详细前面已讲,功能一样,只是事件处理机制不同而已.这里就不再啰嗦.
示例类:
打开 EDTimerExample.as 文档,输入下面的代码:
import AS2.utils.EDTimer;
//----------------------------------------
class EDTimerExample
{
//----------------------------------------
public function EDTimerExample()
{
var te:EDTimer = new EDTimer(1000, 5);
te.addEventListener("timer", this);
te.addEventListener("timerComplete", this);
te.start();
}
private function timer(evt:Object):Void
{
trace("timer: " + evt.currentCount);
}
private function timerComplete(evt:Object):Void
{
trace(evt.type);
}
//----------------------------------------
}
示例 fla 文档:
打开 EDTimerExample.fla 文档,将"图层 1" 重命名为 Actions.并在第一帧中输入下面的代码:
new EDTimerExample();
测试 Flash 文档.输出面板会陆续显示以下的内容:
timer: 1
timer: 2
timer: 3
timer: 4
timer: 5
timerComplete
下一节:[6.建立强大的事件处理机制]
[6.建立强大的事件处理机制]
这一节讲建立强大的事件处理机制.学完这节,如果有接触过 AS3 的,马上会想到一句:这不就是 AS3 的事件处理机制吗?
的确.可以说跟 AS3 的事件处理机制一模一样.但还是有个作用域的问题.这节对想学习 AS3 的事件处理机制会有很大
帮助.如果你掌握这节中的内容,在 AS3 中就只有语法问题.也就会很快进入状态.毕竟是"水往低处流,人往高处走".对现
在用 AS2 的,学 AS3 是迟早的问题.不过 AS2 在新版本出来之前还是会很有用的(个人的看法).
作用域因为一样,前面也讲过,这里就不在啰嗦.
事件对象.这里已经创建一个 Event 类(或其子类)来代替.但功能一样.
这节讲的事件处理机制的形态(代码).
发送事件:
//继承.
import AS2.events.Event;
import AS2.events.CFEventDispatcher;
class className extends CFEventDispatcher
{
...
this.dispatchEvent(new Event(Event.COMPLETE));
...
}
或
//不继承.
import AS2.events.Event;
import AS2.events.CFEventDispatcher;
class className
{
public var addEventListener:Function;
public var removeEventListener:Function;
private var dispatchEvent:Function;
public function className()
{
//此方法要在使用 dispatchEvent 方法前被执行.一般放于构造函数中.
CFEventDispatcher.initialize(this);
}
...
this.dispatchEvent(new Event(Event.COMPLETE));
...
}
侦听事件:
//使用自定义函数.
import AS2.events.Event;
import className;
...
var cn:className = new className();
//自定义函数.
function completeHandler(evt:Event):Void
{
trace(this); //输出: _level0.cn
}
cn.addEventListener(Event.COMPLETE, completeHandler);
...
或
//使用事件侦听器对象.
import AS2.events.Event;
import className;
...
var cn:className = new className();
//事件同名函数.
function complete(evt:Event):Void
{
trace(this); //输出: this(指向侦听器对象)
}
cn.addEventListener(Event.COMPLETE, this);
...
移除侦听:
//使用自定义函数.
...
cn.removeEventListener(Event.COMPLETE, completeHandler);
...
或
//使用事件侦听器对象.
...
cn.removeEventListener(Event.COMPLETE, this);
...
AS2.utils.CFDelegate;
AS2.events.Event;
AS2.events.CFEventDispatcher;
这些是什么?下面讲解:
[6.1.创建 CFDelegate 类(修改 Delegate 类)]
CFDelegate 类是 Delegate 类的修改版本.简化了代码(一般不用的功能).提高了执行效率.
此类文档详细:
Classes/AS2/utils/CFDelegate.as
主类:
打开 CFDelegate.as 文档.输入下面的代码:
class AS2.utils.CFDelegate
{
public static function create(scope:Object, method:Function):Function
{
var f:Function = function ()
{
method.apply(scope, arguments);
};
return f;
}
}
保存文档.
[6.2.创建 CFEventDispatcher 类(修改 EventDispatcher 类)]
CFEventDispatcher 类是 EventDispatcher 类的修改版本.简化了代码(一般不用的功能).提高了执行效率.
此类文档详细:
Classes/AS2/events/CFEventDispatcher.as
主类:
打开 CFEventDispatcher.as 文档.输入下面的代码:
*/
//----------------------------------------
class AS2.events.CFEventDispatcher
{
//----------------------------------------
//构造函数
public function CFEventDispatcher(){}
//----------------------------------------
//当不继承此类时,此属性才有效.
private static var _ed:CFEventDispatcher;
//----------------------------------------
private static function _removeEventListener(queue:Object, handler):Void
{
/*
这里主要用于删除事件数组中的事件处理器.
*/
if (queue != undefined) {
var l:Number = queue.length;
while(l--){
if(queue[l] == handler){
queue.splice(l, 1);
return;
}
}
}
}
//当不继承此类时.此方法有效.
public static function initialize(o:Object):Void
{
/*
如果没有继承此类,而是使用 initialize 此方法时, _ed 等于 undefined.然后创建此类的实例.
最后将事件通知和侦听器管理功能添加到 initialize 方法中的对象 o.
前面所讲的不继承此类时需添加的三个方法,其实是四个.还有 dispatchQueue 方法.但此方法在
调用 dispatchEvent 方法时就会自动调用.可能有人会问,为什么没有定义就能调用?因为在函数
中可以操作对象.从而对对象动态添加方法和属性.这里就是用了在函数中操作对象.
*/
if (_ed == undefined) {
_ed = new CFEventDispatcher();
}
o.addEventListener = _ed.addEventListener;
o.removeEventListener = _ed.removeEventListener;
o.dispatchEvent = _ed.dispatchEvent;
o.dispatchQueue = _ed.dispatchQueue;
}
//----------------------------------------
private function dispatchQueue(queueObj:Object, eventObj:Object):Void
{
/*
这里主要用于判断事件处理器是对象还是函数.
*/
if (queueObj[eventObj.type] != undefined) {
for (var i:String in queueObj[eventObj.type]) {
var o = queueObj[eventObj.type][i];
if (typeof (o) == "object" || typeof (o) == "movieclip") {
//调用对象中的handleEvent函数.
//if (o.handleEvent != undefined) {
//o.handleEvent(eventObj);
//}
//调用对象中的事件同名函数.
//if (o[eventObj.type] != undefined) {
o[eventObj.type](eventObj);
//}
} else {
//调用自定义函数.
o.apply(queueObj, [eventObj]);
}
}
}
}
public function dispatchEvent(eventObj:Object):Void
{
//将事件源始终指向this(应用此类的对象).
eventObj.target = this;
//此句对动态类,或在类中定义"事件名Handler" 这样的函数时才有效.在这里我注释了这句.你如果你想用,可以启用它.
/*
用法: 对象.事件名Handler = function(evt:Object){};
*/
//this[eventObj.type + "Handler"](eventObj);
this.dispatchQueue(this, eventObj);
}
public function addEventListener(event:String, handler):Void
{
//这里可以这样理解:
/*
使用
addEventListener("click", 事件处理器);
添加事件.
这时, this["click"] 就等于 undefined.
(this["click"] == undefined) = true
然后将创建一个新数组来存储事件处理器.
this["click"] = [];
然后执行
CFEventDispatcher._removeEventListener(this["click"], 事件处理器);
来检测此事件是否有相同的事件处理器.如果是就删除它.
举个例:当你在一个网站注册用户名时.网站的注册程序会从数据库中检测是否有与你相同的用户名.
如果有将会提示你重新输入用户名(在这里就是直接删除了).如果没有就会注册成功(这里就在后面
执行 push).但是网站的注册程序不会从数据库中检测是否有与你相同的密码.
就是说一个事件,可添加多个不同的事件处理器,但不能添加相同的事件处理器.
当添加新的事件时,也是一样的
最后使用
this["click"].push(事件处理器);
将事件处理器添加到事件数组.
*/
if (this[event] == undefined) {
this[event] = new Array();
}
//ASSetPropFlags 是隐藏的方法.用它和不用它貌似没有区别.大家可以研究下.
//_global.ASSetPropFlags(this, event, 1);
CFEventDispatcher._removeEventListener(this[event], handler);
this[event].push(handler);
}
public function removeEventListener(event:String, handler):Void
{
//这里我就不啰嗦了.
CFEventDispatcher._removeEventListener(this[event], handler);
}
//----------------------------------------
}
保存文档.
[6.3.创建 Event 类(事件基类,继承 Object 类)]
你可以把它看作事件对象.因应它的工作就是生成事件对象.
此类文档详细:
Classes/AS2/events/Event.as
主类:
打开 Event.as 文档.输入下面的代码:
class AS2.events.Event extends Object
{
//----------------------------------------
//事件的常数名.
public static var COMPLETE:String = "complete";
public static var CANCEL:String = "cancel";
public static var CHANGE:String = "change";
public static var CLOSE:String = "close";
public static var CONNECT:String = "connect";
public static var FULLSCREEN:String = "fullScreen";
public static var OPEN:String = "open";
public static var REMOVED:String = "removed";
public static var RESIZE:String = "resize";
public static var SCROLL:String = "scroll";
public static var SELECT:String = "select";
//----------------------------------------
public var type:String;
public var target:Object;
//----------------------------------------
private var className:String = "Event";
//----------------------------------------
//构造函数.
public function Event(type:String)
{
this.type = type;
}
//----------------------------------------
public function toString():String
{
var str:String = "";
for (var i:String in this) {
if (this[i] != undefined) {
str += i + "=" + this[i] + " ";
}
}
return "[" + this.className + " " + str.slice(0,str.length - 1) + "]";
}
//----------------------------------------
}
保存文档.
此类包含下面内容:
1.事件的常数名.如:
public static var COMPLETE:String = "complete";
...
2.基本的属性.如:
public var type:String;
...
3.className 属性.如:
private var className:String = "Event";
4.构造函数.如:
public function Event(type:String)
{
this.type = type;
}
5.toString() 方法.如:
public function toString():String
{
var str:String = "";
for (var i:String in this) {
if (this[i] != undefined) {
str += i + "=" + this[i] + " ";
}
}
return "[" + this.className + " " + str.slice(0,str.length - 1) + "]";
}
如果你嫌此方法阻碍你的执行效率.可以改成如下(标准):
public function toString():String
{
return "[object " + this.className + "]";
}
这里讲下 toString() 方法.在类中定义此方法.在输出此类实例名实调用此方法.如:
class className
{
...
private var className:String = "className";
public function toString():String
{
return "[object " + this.className + "]";
}
...
}
import className;
var cn:className = new className();
trace(cn);// 调用 toString() 方法.输出: [object className]
当然你也可以改成 AS3 中 Event 类一样的方法.但没有必要,很少会用到.
如果要向 Event 类传递参数和定义新的事件名,请看下面.
[6.4.创建 IOErrorEvent 类(错误事件类,继承 Event 类)]
此类文档详细:
Classes/AS2/events/IOErrorEvent.as
主类:
打开 IOErrorEvent.as 文档,输入下面的代码:
import AS2.events.Event;
//----------------------------------------
class AS2.events.IOErrorEvent extends Event
{
//----------------------------------------
//事件的常数名.
public static var IO_ERROR:String = "IOError";
//----------------------------------------
//属性参数.
public var text:String;
//----------------------------------------
//className 属性
private var className:String = "IOErrorEvent";
//----------------------------------------
//在构造函数中添加参数.
public function IOErrorEvent(type:String, text:String)
{
super(type);
this.text = text;
}
//----------------------------------------
}
保存文档.
[6.5.创建 HTTPStatusEvent 类(http状态事件类,继承 Event 类)]
此类文档详细:
Classes/AS2/events/HTTPStatusEvent.as
主类:
打开 HTTPStatusEvent.as 文档.输入下面的代码:
import AS2.events.Event;
//----------------------------------------
class AS2.events.HTTPStatusEvent extends Event
{
//----------------------------------------
//事件的常数名.
public static var HTTP_STATUS:String = "httpStatus";
//----------------------------------------
//属性参数.
public var status:Number;
//----------------------------------------
//className 属性
private var className:String = "HTTPStatusEvent";
//----------------------------------------
//在构造函数中添加参数.
public function HTTPStatusEvent(type:String, status:Number)
{
super(type);
this.status = status;
}
//----------------------------------------
}
保存文档.
[6.6.示例: EventClass 类(简单的示例)]
此示例文档详细:
Example/AS2/events/Event/EventClass.as
Example/AS2/events/Event/EventExample.as
Example/AS2/events/Event/EventExample.xml
Example/AS2/events/Event/EventExample.fla
主类:
打开 EventClass.as 文档.输入下面的代码:
import AS2.utils.CFDelegate;
import AS2.events.Event;
import AS2.events.IOErrorEvent;
import AS2.events.HTTPStatusEvent;
import AS2.events.CFEventDispatc