(如蒙转载,请留下我的Blog链接:www.kingda.org, thx)
Event机制作为重头戏,在ActionScript 3.0中加强了很多。更加统一、易用、标准、灵活。
ActionScript 2.0中有众多的事件实现机制:
回顾和比较
AS1.0玩家最爱用onClipEvent(), on(),又方便又直接。缺点在于逻辑分散到了各个舞台元件中,难以管理和维护。更加别说代码重用了。别跟俺说可以Copy, Paste,这不叫重用,这叫低级。
AS2.0中,增加了一些事件处理机制:
1.回调函数: onLoad, onComplete等。相信兄弟们最熟悉的应该就是XML.onload回调函数了。
2.事件侦听器型:
这个就是addListener(), addEventListener()这种类型的。发送事件有的是内置,有的通过dispatchEvent().
嗯,这种事件机制基本上就和AS3.0很像了。自从使用了ActionScript 2.0来开发项目,黑羽就尽可能的多用这种事件处理机制。这个习惯很好,基本上让黑羽对3.0的机制很快适应过来。
说道这里,黑羽要多扯几句2.0,抱怨一下它的不足,再让大家看看AS3.0的光明大道。
(1).2.0中除了UIComponent能自己发送事件,绝大部分类不能自己发送事件的,比如MovieClip, 或者一些自定义的类。黑羽还制作了一个EventSender的事件发送类来解决。
当然你可以通过扩展来解决MovieClip这些类来解决,但是在一些轻量级或者特殊运用中,还是用黑羽这个EventSender类更加方便。
比如说,你突然需要舞台上某个A_mc的运行到第20帧时发送一个"finished"事件出来,并且希望另外某个B_mc能够捕捉到这个事件,那么用一般的扩展方法不知道有多么麻烦!
(1.要重做一个带有事件发送功能的类和A_mc通过某种方式绑定。2.同时确保在B_mc中要能访问到发送事件的对象并addEventListenr)。
而用俺的EventSender类非常简单,A_mc中写 EventSender.send("finished", this), B_mc中写EventSender.addListener("finished", listenerFunc),并可以通过event.target属性直接定位A_mc,真是简单的不能再简单了。(请尽量以正规方法为主,不推荐频繁使用,不是好的编程习惯)
![]()
(2)2.0中,侦听器的记忆是"有毛病"的。如果是新手,会经常觉得侦听器函数的this关键字指向飘忽不定,常常弄错。而且看看高手的代码,一会儿是Object做侦听器,一会儿是function做侦听器,真是让人头痛。其实MacroMedia也很头痛,所以就出了Delegate这个官方类(补丁?)来解决这些问题。
(3)侦听器注册方式也有两种,一种是addListener(),如Key,一种是addEventListener(),如UIComponent类。为什么要这样搞两种?MacroMedia无辜的望着我,喃喃道偶也不完全清楚。
超人来了,那就是ActionScript 3.0事件处理机制:
(1)统一。全部一色用addEventListener().
(2)所有的可视对象都可以接受和发送事件。
AS3.0的类继承设计是深思熟虑的,所有的可视对象所属类都是DisplayObject的子类, DisplayObject又是EventDispatcher的子类。因此它们就都可以玩Event了,所以说,有个好的老子就是好啊。
而且有了崭新的事件冒泡机制,可以使事件层层上递到最上层的Stage,绝好的功能!
有了以上两点:黑羽的EventSender类也可以歇菜了。
(3)侦听器统一使用Function,不再使用Object了。 同时this关键字的记忆力“大大增强”,Delegate类也可以下岗了。
Event涉及到的内容极多,面很广。下面黑羽将从以下几个方面讲起:
一、如何接收事件?如何做到AS3.0的标准事件编程。
二、如何发送自定义事件?如何在OOP中正确使用AS3.0强大灵活的事件架构。
三种方式及其优劣,以及在何种情况下使用。
(1)用继承EventDispatcher实现
(2)用复合EventDispatcher实例来实现。
(3)用接口IEventDispatcher实现
三、如何使用冒泡机制(即官方所称的Event Flow机制)?以及冒泡机制的原理。
四、Event的其他高级应用。
P.S:本教程受Creative Commons License.协议保护,未经作者同意,不得用于商业用途。







Comments (18)
正在学习,期待下篇
Posted by eidiot | July 26, 2006 6:35 AM
Posted on July 26, 2006 06:35
一般继承eventdispatcher比较多
Posted by saicn | July 26, 2006 9:07 AM
Posted on July 26, 2006 09:07
to saicn:
是的,一般情况下继承EventDispatcher比较多。^^
但是第二种方法会经常需要用到。第三种使用接口的方式,在某些特殊情况下必须使用,比如说在别人项目的基础上进行修改时会碰到这种情况。
Posted by 黑羽 | July 26, 2006 9:27 AM
Posted on July 26, 2006 09:27
对其事件看了下,相应的对象都提供了对应的事件。在EventDispatcher还是基本上走了当初V2组件的事件机制。enterframe的改动比较大,在这方面多了Timer,setTimeout/clearTimeout,的确不错。
Posted by 逍遥云 | July 26, 2006 9:41 AM
Posted on July 26, 2006 09:41
对其事件看了下,相应的对象都提供了对应的事件。在EventDispatcher还是基本上走了当初V2组件的事件机制。enterframe的改动比较大,在这方面多了Timer,setTimeout/clearTimeout,的确不错。
Posted by 逍遥云 | July 26, 2006 9:42 AM
Posted on July 26, 2006 09:42
不好意思,多发了一条,删除:)
Posted by 逍遥云 | July 26, 2006 9:44 AM
Posted on July 26, 2006 09:44
如果给一个object增加一个listener:
obj.addEventListener(MouseEvent.CLICK,ShowHandler);
如果obj的focus失去以后,这个事件就无法监听到了!这种问题怎么解决?谢谢
Posted by veteran | July 26, 2006 10:57 AM
Posted on July 26, 2006 10:57
黑羽是不是现在开始全面进攻AS3.0了?好象学的很Happy啊!
:)
Posted by zikey | July 26, 2006 2:08 PM
Posted on July 26, 2006 14:08
to veteran:
你的问题我不太明白。如果是要监听CLICK事件的话,必定会拥有焦点的啊。说详细点看靠近。
to zikey:
呵呵,AS3.0太吸引人了。其实我已经用了一段时间了,有了一些开发笔记。
Posted by 黑羽 | July 27, 2006 9:26 AM
Posted on July 27, 2006 09:26
我的意思是:如果我想用键盘来控制一个球的话,必须首先焦点在这个球上,如果失去了这个焦点,就不能控制了,我想问的是有没有合理一点的办法来对键盘进行监听,一直可以控制这个球。
Posted by veteran | July 27, 2006 3:07 PM
Posted on July 27, 2006 15:07
如果我理解的根本就是错误的,请指出正确的键盘监听的方法!谢谢
Posted by veteran | July 27, 2006 3:10 PM
Posted on July 27, 2006 15:10
黑羽你老人家辛苦了 。
Posted by sonygod | July 28, 2006 9:06 AM
Posted on July 28, 2006 09:06
期待下一篇教程哦
Posted by laixin | July 28, 2006 10:23 AM
Posted on July 28, 2006 10:23
期待能买到你写的as3 的书
快联系出版社,我相信很多人抢购!
Posted by rocks | July 28, 2006 4:11 PM
Posted on July 28, 2006 16:11
是篇不错的教程
不过通篇出现无数个“黑羽”还都加上链接 不解 .\/.
Posted by Neo | August 11, 2006 12:21 PM
Posted on August 11, 2006 12:21
老兄你的文笔不错,看你的文章虽然是技术方面的但一点都不感觉到累或者枯燥!你有QQ吗,我的是46211256希望多多交流
Posted by eric | June 6, 2007 5:24 PM
Posted on June 6, 2007 17:24
呵呵,我又跑这儿来了,关于昨天Eclipse+FDT的问题还是不太明白,即使是用FDT3导入ADOBE官方的范例类,也会连篇报错,尤其是在Objcet对象内定义的属性或是事件都会到Objcet的原类中去找,如Objcet.eventname,不知道您都是怎样解决的?
Posted by Merrycat | September 13, 2007 1:40 PM
Posted on September 13, 2007 13:40
呵呵,我又跑这儿来了,关于昨天Eclipse+FDT的问题还是不太明白,即使是用FDT3导入ADOBE官方的范例类,也会连篇报错,尤其是在Objcet对象内定义的属性或是事件都会到Objcet的原类中去找,如Objcet.eventname,不知道您都是怎样解决的?
import mx.data.components.XMLConnector;
class com.Merrycat.xmlConn.XmlConn extends Object {
xmlConnector : XMLConnector;
public function XmlConn() {
xmlConnector = new XMLConnector();
init();
}
private function init() : Void {
xmlConnector.URL = "test.xml"
xmlConnector.direction = "receive";
xmlConnector.addEventListener("result", result);
xmlConnector.trigger();
}
private function result(event : XmlConn) : Void {
trace(event.target.results);
}
}
Posted by Merrycat | September 13, 2007 1:41 PM
Posted on September 13, 2007 13:41