Flex事件机制的工作流程

Flex事件机制的工作流程

事件机制的工作流程

关于事件流

目标对象:派发事件的对象
当事件发生后生成一个携带数据的对象,然后检查目标对象是否存在显示层中,并遍历从根容器一直到目标对象所在位置的所有对象,以树形势表示。自动检测所经过的节点是否注册了监听器。

事件流暗运行流程分为3步:
  • 捕获阶段:捕获事件 capturing,从根节点开始顺序而下,检测每个节点是否注册了监听器。同时,Flex 将事件对象的currentTarget 值改为当前正在检测的对象。如果注册了监听器,则调用监听函数。
  • 目标阶段:检测目标的监听器 targeting:触发在目标对象本身注册的监听程序
  • 冒泡阶段:事件冒泡 bubbling:从目标节点到根节点,检测每个节点是否注册了监听器,如果有,则调用监听函数。

每个事件对象都有以下属性:
target:事件的派发者
currentTarget:当前正在检测的的对象,帮助跟踪事件传播的过程。

默认情况下,捕获功能处于关闭状态,一般没有必要进行捕获跟踪。
事件只在bubbles 属性为true 时才进行冒泡,可以冒泡的事件包括:change、click、doubleClick、keyDown、keyUp、mouseDown、 mouseUp。并且不能在一个监听器中同时打开捕获和冒泡功能,要做到这一点,只能注册两个监听器,分别实现。

现在来看一个例子:
Xml代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">     
  3.     <mx:Style source="style.css" />  
  4.      
  5.     <mx:Script>  
  6.         <![CDATA[ 
  7.             import flash.events.MouseEvent; 
  8.             
  9.             internal function initApp():void{ 
  10.                 canvas_1.addEventListener(MouseEvent.CLICK,pressBtn,true); 
  11.                 canvas_2.addEventListener(MouseEvent.CLICK,pressBtn); 
  12.                 btn_1.addEventListener(MouseEvent.CLICK,pressBtn); 
  13.                 btn_2.addEventListener(MouseEvent.CLICK,pressBtn); 
  14.             } 
  15.             internal function output(msg:String):void{ 
  16.                 debug_txt.text += msg+"\n"; 
  17.             }            
  18.             internal function pressBtn(evt:MouseEvent):void{ 
  19.                 output("是否冒泡--"+evt.bubbles); 
  20.                 output("目标对象-- "+evt.target+" -- "+evt.eventPhase); 
  21.                 output("遍历对象-- "+evt.currentTarget); 
  22.                 output("------------"); 
  23.             } 
  24.         ]]>  
  25.     </mx:Script>  
  26.     <mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="445" height="216">  
  27.         <mx:Text x="13" y="10" text="Canvas_1"/>  
  28.         <mx:Canvas id="canvas_2" styleName="box" x="10" y="102" width="173" height="90">  
  29.             <mx:Text x="10" y="10" text="Canvas_2"/>  
  30.             <mx:Button id = "btn_2" x="10" y="38" label="Button_2"/>             
  31.         </mx:Canvas>  
  32.         <mx:Button id="btn_1" x="16" y="38" label="Button_1"/>  
  33.     </mx:Canvas>  
  34.     <mx:TextArea id="debug_txt" styleName="textBox" x="37" y="304" height="198" width="445"/>  
  35.      
  36. </mx:Application>  
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Style source="style.css" />
<mx:Script>
<![CDATA[
import flash.events.MouseEvent;
internal function initApp():void{
canvas_1.addEventListener(MouseEvent.CLICK,pressBtn,true);
canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);
btn_1.addEventListener(MouseEvent.CLICK,pressBtn);
btn_2.addEventListener(MouseEvent.CLICK,pressBtn);
}
internal function output(msg:String):void{
debug_txt.text += msg+"\n";
}
internal function pressBtn(evt:MouseEvent):void{
output("是否冒泡--"+evt.bubbles);
output("目标对象-- "+evt.target+" -- "+evt.eventPhase);
output("遍历对象-- "+evt.currentTarget);
output("------------");
}
]]>
</mx:Script>
<mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="445" height="216">
<mx:Text x="13" y="10" text="Canvas_1"/>
<mx:Canvas id="canvas_2" styleName="box" x="10" y="102" width="173" height="90">
<mx:Text x="10" y="10" text="Canvas_2"/>
<mx:Button id = "btn_2" x="10" y="38" label="Button_2"/>
</mx:Canvas>
<mx:Button id="btn_1" x="16" y="38" label="Button_1"/>
</mx:Canvas>
<mx:TextArea id="debug_txt" styleName="textBox" x="37" y="304" height="198" width="445"/>
</mx:Application>
 
在监听函数 pressBtn 中的属性说明:
  • target:派发事件的目标对象
  • currentTarget:事件流当前正经过的目标对象
  • bubbles:是否打开了冒泡功能
  • eventPhase:事件流当前的阶段,1:捕获,2:目标,3:冒泡


addEventListener(
  type:String,    事件的类型
  listener:Function,    监听函数
  useCapture:Boolean = false,    是否打开捕获功能
  priority:int = 0,    监听器优先级别
  useWeakReference:Boolean = false    是否使用弱引用
)

如果useCapture 为true,打开了捕获功能,则该组件的冒泡阶段被取消。
只有可视化的对象有3个阶段,而像XML等非可视化对象只有目标阶段。

 

 

8.2.2 事件对象

EventDispatcher 是派发事件的武器,经它派发的事件对象必须是Event类型或者Event的子类。
Event对象中包含目标对象存放的数据,这些数据都成为Event的属性,以供侦听器使用:
Event的属性:
  • bubbles:只读,布尔,事件是否开启冒泡功能
  • cancelable:只读,布尔,处理事件的默认行为是否可以停止。主要针对一些系统事件,如果值为true,则Event的preventDefault方法可以使用,否则不可用。
  • currentTarget:只读,对象,当前正在调用监听器的对象
  • eventPhase:只读,整数,返回事件流正经历的阶段。1:捕获,2:目标,3:冒泡
  • target:只读,派发事件的目标对象
  • type:只读,字符,事件类型。比如鼠标点击事件的类型:click,并被定义为常量:MouseEvent.CLICK

构造函数:
Event(
  type:String,    事件类型
  bubbles:Boolean = false,   是否冒泡
  cancelable:Boolean = false  是否可以停止
)

Event 的方法:
  • isDefaultPrevented:判断preventDefault 是否已经被调用
  • preventDefault:停止事件的默认行为。针对一些系统事件,cancelable为true时才可用。
  • stopImmediatePropagation:停止当前的事件流传播,包括当前正在处理的对象
  • stopPropagation:停止当前的事件流传播,但不会停止当前正在处理的对象

 

Xml代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">     
  3.     <mx:Style source="style.css" />  
  4.      
  5.     <mx:Script>  
  6.         <![CDATA[ 
  7.             import flash.events.MouseEvent; 
  8.             
  9.             internal function initApp():void{ 
  10.                 canvas_1.addEventListener(MouseEvent.CLICK,CanvasHandler); 
  11.                 canvas_2.addEventListener(MouseEvent.CLICK,CanvasHandler); 
  12.                 canvas_2.addEventListener(MouseEvent.CLICK,pressBtn); 
  13.                 btn_1.addEventListener(MouseEvent.CLICK,pressBtn); 
  14.             } 
  15.             internal function output(msg:String):void{ 
  16.                 debug_txt.text += msg+"\n"; 
  17.             } 
  18.             
  19.             internal function pressBtn(evt:MouseEvent):void{ 
  20.  
  21.                 output("是否冒泡--"+evt.bubbles); 
  22.                 output("目标对象-- "+evt.target+" -- "+evt.eventPhase); 
  23.                 output("遍历对象-- "+evt.currentTarget); 
  24.                 output("------------");        
  25.             } 
  26.             internal function CanvasHandler(evt:MouseEvent):void{ 
  27.                 
  28.                 output("目标对象-- "+evt.currentTarget+" -- "+evt.eventPhase); 
  29.                 //停止事件流的传播 
  30.                 evt.stopImmediatePropagation(); 
  31.                 //evt.stopPropagation(); 
  32.             } 
  33.         ]]>  
  34.     </mx:Script>  
  35.     <mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="425" height="160">  
  36.         <mx:Text x="13" y="10" text="Canvas_1"/>  
  37.         <mx:Canvas id="canvas_2" styleName="box" x="10" y="52" width="173" height="90">  
  38.             <mx:Text x="10" y="10" text="Canvas_2"/>  
  39.             <mx:Button id = "btn_1" x="10" y="38" label="Button_1"/>             
  40.         </mx:Canvas>  
  41.     </mx:Canvas>  
  42.     <mx:TextArea id="debug_txt" styleName="textBox" x="37" y="245" height="198" width="425"/>  
  43.      
  44. </mx:Application>  
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Style source="style.css" />
<mx:Script>
<![CDATA[
import flash.events.MouseEvent;
internal function initApp():void{
canvas_1.addEventListener(MouseEvent.CLICK,CanvasHandler);
canvas_2.addEventListener(MouseEvent.CLICK,CanvasHandler);
canvas_2.addEventListener(MouseEvent.CLICK,pressBtn);
btn_1.addEventListener(MouseEvent.CLICK,pressBtn);
}
internal function output(msg:String):void{
debug_txt.text += msg+"\n";
}
internal function pressBtn(evt:MouseEvent):void{
output("是否冒泡--"+evt.bubbles);
output("目标对象-- "+evt.target+" -- "+evt.eventPhase);
output("遍历对象-- "+evt.currentTarget);
output("------------");
}
internal function CanvasHandler(evt:MouseEvent):void{
output("目标对象-- "+evt.currentTarget+" -- "+evt.eventPhase);
//停止事件流的传播
evt.stopImmediatePropagation();
//evt.stopPropagation();
}
]]>
</mx:Script>
<mx:Canvas id = "canvas_1" styleName="box" x="37" y="63" width="425" height="160">
<mx:Text x="13" y="10" text="Canvas_1"/>
<mx:Canvas id="canvas_2" styleName="box" x="10" y="52" width="173" height="90">
<mx:Text x="10" y="10" text="Canvas_2"/>
<mx:Button id = "btn_1" x="10" y="38" label="Button_1"/>
</mx:Canvas>
</mx:Canvas>
<mx:TextArea id="debug_txt" styleName="textBox" x="37" y="245" height="198" width="425"/>
</mx:Application>

 

8.2.3 侦听和响应事件--一个侦听键盘事件的例子

要侦听一个事件,首先要创建一个函数来作为事件处理器,然后将这个函数注册给相应的时间类型。
this. addEventListener(KeyboardEvent.KEY_DOWN,keyHandler);
注册键盘按下事件,交给keyHandler处理,也可以在Application标签添加事件:
keyDown="keyHandler(event)"  这种情况无法移除事件。

注册了事件监听器,使用完毕后,必须使用removeEcentListener 方法删除监听函数:
removeEcentListener(
  type:String,   事件类型
  listener:Function,   监听函数
  useCapture:Boolean = false    是否开启捕获功能,如果注册时打开,移除也要打开。
)

Xml代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"  
  3.      creationComplete="initApp()">  
  4.     <mx:Style source="style.css" />     
  5.     <mx:Script>  
  6.         <![CDATA[ 
  7.             import flash.events.KeyboardEvent; 
  8.  
  9.             internal function initApp():void{ 
  10.                 this.addEventListener(KeyboardEvent.KEY_DOWN,keyHandler); 
  11.             } 
  12.  
  13.             private function keyHandler(e:KeyboardEvent):void{ 
  14.  
  15.                 var str:String = "你按下的是: "+e.keyCode;                
  16.                 debug_txt.text += str +"\n"; 
  17.             } 
  18.         ]]>  
  19.     </mx:Script>     
  20.     <mx:TextArea id="debug_txt" styleName="textBox" x="25" y="78" height="198" width="212" editable="false"/>  
  21.     <mx:Text x="25" y="50" text="按键盘上的任意键"/>  
  22. </mx:Application> 

你可能感兴趣的:(Flex事件机制的工作流程)