作用域因为一样,前面也讲过,这里就不在啰嗦.
事件对象.这里已经创建一个 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