机制说明:
事件机制分为三个阶段,按照先后顺序如下说明(假设Button分发了事件):
捕获阶段(Capture phase):从顶部(如root)到目标;
目标阶段(Target phase):到达目标;
冒泡阶段(Bubbling phase):从目标到顶部。
注:
1、当鼠标点击触发了事件:Button(D);
2、FlashPlayer会将事件对象调度到从显示列表根开始的事件流中:Application;
3、然后该事件对象在显示列表中逐层前进:Application->BorderContainer(A)->BorderContainer(B)->BorderContainer(C)<捕获阶段>
4、直到到达事件目标:Button(D)<目标阶段>
5、然后从事件目标到显示列表根:BorderContainer(C)->BorderContainer(B)->BorderContainer(A)->Application<冒泡阶段>
默认原则:
1、flash.events.Event.Event(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
type 事件的类型,可以作为 Event.type
访问。bubbles 确定 Event 对象是否参与事件流的冒泡阶段。默认值为 false
。cancelable 确定是否可以取消 Event 对象。默认值为 false
。注意:Event默认是参与捕获阶段,而不参与冒泡阶段。
2、flash.events.EventDispatcher.addEventListener(type:String, listener:Function, useCapture:Boolean=false, priority:int=0, useWeakReference:Boolean=false):void
type 事件的类型。 listener 处理事件的侦听器函数。此函数必须接受 Event 对象作为其唯一的参数,并且不能返回任何结果,如下面的示例所示: function(evt:Event):void函数 可以有任何名称。 useCapture 确定侦听器是运行于捕获阶段还是运行于目标和冒泡阶段。如果将 useCapture
设置为true
,则侦听器只在捕获阶段处理事件,而不在目标或冒泡阶段处理事件。如果 useCapture
为false
,则侦听器只在目标或冒泡阶段处理事件。要在所有三个阶段都侦听事件,请调用addEventListener
两次:一次将 useCapture
设置为true
,一次将useCapture
设置为false
。priority 事件侦听器的优先级。优先级由一个带符号的 32 位整数指定。数字越大,优先级越高。优先级为 n 的所有侦听器会在优先级为 n -1 的侦听器之前得 到处理。如果两个或更多个侦听器共享相同的优先级,则按照它们的添加顺序进行处理。默认优先级为 0。 useWeakReference确定对侦听器的引用是强引用,还是弱引用。强引用(默认值)可防止您的侦听器被当作垃圾回收。弱引用则没有此作用。 类级别成员函数不属于垃圾回收的对象,因此可以对类级别成员函数将 useWeakReference
设置为true
而不会使它们受垃圾回收的影响。如果对作为嵌套内部函数的侦听器将 useWeakReference
设置为true
,则该函数将作为垃圾回收并且不再是永久函数。如果创建对该内部函数的引用(将该函数保存到另一个变量中),则该函数将不作为垃圾回收并仍将保持永久。
注意:addEventListener默认是监听冒泡阶段,而不参与捕获阶段。
具体应用:
1、例子
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="initApp(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protected function initApp(event:FlexEvent):void { this.addEventListener("EventName",function(event:Event):void { trace("Appliction-捕获阶段"); },true); this.addEventListener("EventName",function(event:Event):void { trace("Appliction-冒泡阶段"); }); A.addEventListener("EventName",function(event:Event):void { trace("A-捕获阶段"); },true); A.addEventListener("EventName",function(event:Event):void { trace("A-冒泡阶段"); }); C.addEventListener("EventName",function(event:Event):void { trace("C-捕获阶段"); },true); C.addEventListener("EventName",function(event:Event):void { trace("C-冒泡阶段"); }); B.addEventListener("EventName",function(event:Event):void { trace("B-捕获阶段"); },true); B.addEventListener("EventName",function(event:Event):void { trace("B-冒泡阶段"); }); D.addEventListener("EventName",function(event:Event):void { trace("D-目标阶段"); }); } protected function D_clickHandler(event:MouseEvent):void { D.dispatchEvent(new Event("EventName",true)); } ]]> </fx:Script> <fx:Declarations> <!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <s:BorderContainer id="A" width="400" height="250" cornerRadius="5" horizontalCenter="0" verticalCenter="0" backgroundColor="#afaf12"> <s:BorderContainer id="B" width="250" height="150" cornerRadius="5" horizontalCenter="0" verticalCenter="0" backgroundColor="#aaaaaa"> <s:BorderContainer id="C" width="130" height="80" cornerRadius="5" horizontalCenter="0" verticalCenter="0"> <s:Button id="D" horizontalCenter="0" verticalCenter="0" click="D_clickHandler(event)"/> </s:BorderContainer> </s:BorderContainer> </s:BorderContainer> </s:Application>
2、结果
注意:该例子中Event是参与冒泡阶段,addEventListener添加监听捕获阶段和冒泡阶段,上图显示了事件的整个流程。