1.
目标匹配阶段
在目标匹配阶段,Flex调用事件调度者的监听器,Event对象的currentTarget和target属性的值将是相同的。
2.
冒泡阶段
在冒泡阶段,Flex会在事件的祖先(event’s ancestors)中查找事件监听器。Flex将从事件调度者的直接祖先开始向上查找,知道根祖先。这与捕获阶段相反。
例如,如果你的程序有一个Panel容器,Panel容器包含一个TitleWindow容器,TitleWindow容器又包含一个按钮控件,那么程序的结构如下所示:
Application
Panel
TitleWindow
Button
如果你监听按钮控件的点击事件,如果允许冒泡的话,下面的步骤将在冒泡阶段发生:
(1)
检查TitleWindow容器上是否有点击事件监听器;
(2)
检查Panel容器上是否有点击事件监听器;
(3)
检查Application容器上是否有点击事件监听器。
只有在bubbles属性被设定为true时,事件才会冒泡。鼠标事件和键盘事件是冒泡的。可以冒泡的事件包括change,click,doubleClick,keyDown,keyUp,mouseDown和mouseUp。
当Flex调用一个事件监听器时,Event对象可能实际上是被一个显示列表中的深层对象调度。最先调度事件的对象是Event对象的target属性。当前正在冒泡的对象是Event对象的currentTarget对象。所以,当你要引用事件监听器的当前对象时,必须总是使用currentTarget属性而不是target属性。
只有当对象调度事件的时候,你才能为那个对象添加事件监听器。例如,你不能让一个Form容器监听click事件,除非那个容器包含有一个按钮控件。Form容器本身不能调度点击事件。Form容器可以调度mouseDown事件,所以你可以在Form容器上添加moseDown事件监听器。如果你那样做了,每当按钮被点击或者Form容器受到了一个mouseDown事件的时候,你的事件监听器会被调用。
如果你将useCapture属性设置为true,也就是说,如果一个事件在捕获阶段被传播,那么,它将不会冒泡,而不管它默认的冒泡行为。如果你希望你的事件能够同时在捕获阶段和冒泡阶段被传播,你必须调用addEventListener()方法两次:一次将useCapture参数设定为true,另一次将useCapture参数设定为false。
事件只能在显示列表中的祖先链中冒泡。处于同一容器中的两个按钮组件不会拦截对方的事件。
3.
探测事件阶段
你可以通过使用Event对象的eventPhase属性来探查你正在使用哪个阶段。这个属性包含了一个整数。内容描述如下所示:
1:捕获阶段(CAPTURE_PHASE)
2:目标匹配阶段(AT_TARGET)
3:冒泡阶段(BUBBLING_PHASE)
下面的例子展示了当前阶段和当前目标的ID:
import mx.controls.Alert;
private function showInfo(e:MouseEvent):void {
Alert.show("Phase: " + e.eventPhase + "\n" +
"Current Target: " + e.currentTarget.id);
}
]]>
label="Click Me"
click="showInfo(event)"
/>
|
4.
停止传播
在任何阶段,你都可以通过调用下面的方法来组织事件在显示列表中的移动(traversal):
stopPropagation()
stopImmediatePropagation()
你可以通过调用Event对象的stopPropagation()方法和stopImmediatePropagation()方法来阻止Event对象在事件流的路径中继续运行。两者基本相同,不同之处在于当前节点遗留的事件监听器是否允许被调用。stopPropagation()方法只是在当前节点的所有事件监听器被调用后,阻止事件继续向下个节点传递。stopImmediatePropagation()方法同样会组织Event对象向下个节点传递,但是它也不允许当前节点的任何其他事件监听器被执行。
下面的例子创建了一个Panel容器,包含有一个TitleWSindow容器。两个容器都被注册了mouseDown事件监听器。如果你在TitleWindow容器中点击鼠标,showAlert()方法将被调用两次,除非你调用stopImmediatePropagation()方法。如下所示:
import mx.controls.Alert;
import flash.events.MouseEvent;
import flash.events.Event;
public function init(e:Event):void {
p1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
tw1.addEventListener(MouseEvent.MOUSE_DOWN, showAlert);
tw1.addEventListener(Event.CLOSE, closeWindow);
p2.addEventListener(MouseEvent.MOUSE_DOWN,
showAlertWithoutStoppingPropagation);
tw2.addEventListener(MouseEvent.MOUSE_DOWN,
showAlertWithoutStoppingPropagation);
tw2.addEventListener(Event.CLOSE, closeWindow);
}
public function showAlert(e:Event):void {
Alert.show("Alert!\n" + "Current Target: " + e.currentTarget + "\n" +
"Phase: " + e.eventPhase);
e.stopImmediatePropagation();
}
public function showAlertWithoutStoppingPropagation(e:Event):void {
Alert.show("Alert!\n" + "Current Target: " + e.currentTarget + "\n" +
"Phase: " + e.eventPhase);
}
public function closeWindow(e:Event):void {
p1.removeChild(tw1);
}
]]>
width="300"
height="100"
showCloseButton="true"
title="Title Window 1"
>
width="300"
height="100"
showCloseButton="true"
title="Title Window 2"
>
|