我在AS3事件的最后一块拼图上遇到了困难。
我知道目标类继承自EventDispatch或实现IEventDispatch,并且可以注册(以及其他方法)事件侦听器。
但是,目标类用什么注册?如果事件发生,AS3如何知道将事件传递给目标类?
谨致问候,shwell。
阅读这篇关于事件阶段的文章,它将更有意义:
http://livedocs.adobe.com/flex/3/html/help.html?content=events_02.html
希望这能有所帮助。祝你今天过得愉快。
您可以了解starling事件是如何在中工作的
starling偶数调度器
当displayObject为事件设置气泡时,它将检查displayObject的父对象是否存在,并将父对象添加到bubbleList(如果存在),直到displayObject祖先为null。
以下代码位于starling eventDispatcher 中
var element:DisplayObject = this as DisplayObject;
var chain:Vector.<EventDispatcher> = new <EventDispatcher>[element];
while ((element = element.parent) != null)
chain[int(length++)] = element;
在AS3中,EventDispatcher
是观察器设计模式的实现。此类实现addEventLister
、removeEventListener
、dispatchEvent' and
hasEventListener`方法。在内部,它还维护一个字典或类似的数据结构,其中包含当前正在侦听的事件,以及在调度事件时必须调用的方法列表。类似这样的东西-
{"event1": [method7, method5, method3], "event2": [method3, method2], "event3": [method1]};
当对对象调用addEventListener
时,它会为有问题的事件创建一个新键,并将方法引用添加到其关联的值列表中。
当对类调用dispatchEvent
时,它会获取与该事件相关联的所有方法,并调用与其关联的方法。每个方法都是用Event
类或其子类的一个实例调用的。
删除事件侦听器显然与添加相反。
我想你错过了addEventListener()
机制。这件事对事件引擎有全局副作用,注册回调函数和调用方this
值,以提供触发事件的正确上下文,并可能通过静态或动态调用globalToLocal()
来更新event.localX
和event.localY
属性,因为事件上下冒泡。
如果你和我一样,对Flash播放器如何确定事件的目标感到困惑——有一个内部的"焦点"指针可以确定SWF的哪个组件具有键盘焦点,而这个指针用于确定键盘事件的目标。对于鼠标事件,Flash引擎很可能会调用getObjectsUnderPoint()
来查询最顶层的IEventDispatcher
兼容对象(并非所有DisplayObjects都能处理事件),并向该对象发送鼠标事件,如果目标已更改,则前一个事件的目标将接收MouseEvent.ROLL_OUT
或MouseEvent.MOUSE_OUT
。对于其他事件,很可能整个显示列表都会做出反应。
对于显示列表中的对象,以下Adobe摘录的答案是"当Adobe®Flash®Player调度一个Event对象时,该Event对象会从显示列表的根节点往返到目标节点,检查每个节点是否有注册的侦听器。"。
对于非显示对象,AS3运行时维护一个包含绑定变量的所有AS3事件的字典。绑定变量是对事件侦听器的引用。