本人比较懒,文笔也不怎样,想总结的时候就去网上搜搜同志们写的文章,然后把有选择的记录一些。以下的几篇文章关于事件流的理解大同小异,写东西不怎么勤快,copy.past还是比较勤快
第一个应该是最权威的说法
只要发生事件,Flash Player 就会调度事件对象。如果事件目标不在显示列表中,则 Flash Player 将事件对象直接调度到事件目标。例如,Flash Player 将 progress 事件对象直接调度到 URLStream 对象。但是,如果事件目标在显示列表中,则 Flash Player 将事件对象调度到显示列表,事件对象将在显示列表中穿行,直到到达事件目标。
“事件流”说明事件对象如何在显示列表中穿行。显示列表以一种可以描述为树的层次结构形式进行组织。位于显示列表层次结构顶部的是舞台,它是一种特殊的显示对象容器,用作显示列表的根。舞台由 flash.display.Stage 类表示,且只能通过显示对象访问。每个显示对象都有一个名为 stage
的属性,该属性表示应用程序的舞台。
当 Flash Player 调度事件对象时,该事件对象进行一次从舞台到“目标节点”的往返行程。DOM 事件规范将目标节点定义为代表事件目标的节点。也就是说,目标节点是发生了事件的显示列表对象。例如,如果用户单击名为 child1
的显示列表对象,Flash Player 将使用 child1
作为目标节点来调度事件对象。
从概念上来说,事件流分为三部分。第一部分称为捕获阶段,该阶段包括从舞台到目标节点的父节点范围内的所有节点。第二部分称为目标阶段,该阶段仅包括目标节点。第三部分称为冒泡阶段。冒泡阶段包括从目标节点的父节点返回到舞台的行程中遇到的节点。
如果您将显示列表想像为一个垂直的层次结构,其中舞台位于顶层(如下图显示),那么这些阶段的名称就更容易理解了:
如果用户单击 Child1
,Flash Player 将向事件流调度一个事件对象。如下面的图像所示,对象的行程从 Stage
开始,向下移动到 Parent
,然后移动到 Child1
,再“冒泡”返回到 Stage
:在行程中重新经过 Parent
,再返回到 Stage
。
在该示例中,捕获阶段在首次向下行程中包括 Stage
和 Parent
。目标阶段包括在 Child1
花费的时间。冒泡阶段包括在向上返回到根节点的行程中遇到的 Parent
和 Stage
。
事件流使现在的事件处理系统比 ActionScript 程序员以前使用的事件处理系统功能更为强大。早期版本的 ActionScript 中没有事件流,这意味着事件侦听器只能添加到生成事件的对象。在 ActionScript 3.0 中,您不但可以将事件侦听器添加到目标节点,还可以将它们添加到事件流中的任何节点。
当用户界面组件包含多个对象时,沿事件流添加事件侦听器的功能十分有用。例如,按钮对象通常包含一个用作按钮标签的文本对象。如果无法将侦听器添加到事件流,您将必须将侦听器添加到按钮对象和文本对象,以确保您收到有关在按钮上任何位置发生的单击事件的通知。而事件流的存在则使您可以将一个事件侦听器放在按钮对象上,以处理文本对象上发生的单击事件或按钮对象上未被文本对象遮住的区域上发生的单击事件。
不过,并非每个事件对象都参与事件流的所有三个阶段。某些类型的事件(例如 enterFrame
和 init
类型的事件)会直接调度到目标节点,并不参与捕获阶段和冒泡阶段。其它事件可能以不在显示列表中的对象为目标,例如调度到 Socket 类的实例的事件。这些事件对象也将直接流至目标对象,而不参与捕获和冒泡阶段。
要查明特定事件类型的行为,可以查看 API 文档或检查事件对象的属性。下面的部分介绍了如何检查事件对象的属性。
http://livedocs.adobe.com/flash/9.0_cn/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000137.html#wp826683
next stone -->
事件流
1.捕获阶段(从根节点到子节点,检测对象是否注册了监听器,是则调用监听函数)
2.目标阶段(调用目标对象本身注册的监听程序)
3.冒泡阶段(从目标节点到根节点,检测对象是否注册了监听器,是则调用监听函数)
注:事件发生后,每个节点可以有2个机会(2选1)响应事件,默认关闭捕获阶段。
从上到下(从根到目标)是捕获阶段,到达了目标后是目标阶段,然后从目标向上返回是冒泡阶段。
怎样理解事件流?
当事件发生时,FLEX通过事件的分发器EventDispatcher进行事件分发,分发的顺序是:从上往下到达目标,然后从下往上,从目标开始返回。如上面1、2、3所说的那样,这里就会有一个问题,在事件的流经过程中,不是目标的对象如果注册了事件,也有了相应的事件响应函数,那么不是目标的对象响应了事件的处理,这怎么办呢?
由于上面说的那样,addEventListener在只有如上两个参数的牧人情况下是关闭捕获阶段的,也就是说事件流是从目标阶段开始的,然后是冒泡阶段,当出现容器包含控件的时候,可以使用判断
if(evt.target == evt.currentTarget)
来确定当前事件流上的当前流经对象是否就是目标对象,如果是就进行相应的处理。
移除对象的事件流:removeEventListener(),参数与注册事件相同。
阻断事件流中目标对象的后继事件,即通过了目标阶段后阻止冒泡阶段:
event类的方法:public function stopImmediatePropagation():void
Event类
Event 类作为创建 Event 对象的基类,当发生事件时,Event 对象将作为参数传递给事件侦听器。 如MouseEvent 、KeyboardEvent ,更多的可以查参考手册。
Event类有几个常用的公共属性:
是否冒泡:bubbles;
目标对象:target;
所处阶段:eventPhase;
当前对象:currentTarget;
从参考手册可以event类的构造函数:
Event () 构造函数 public function Event(type:String, bubbles:Boolean = false,cancelable:Boolean = false)
创建一个作为参数传递给事件侦听器的 Event 对象。
参数 type:String — 事件的类型,可以作为 Event.type 访问。
bubbles:Boolean (default = false) — 确定 Event 对象是否参与事件流的冒泡阶段。 默认值为 false。
cancelable:Boolean (default = false) — 确定是否可以取消 Event 对象。 默认值为 false。
在flash.events包中可以看见系统自带的事件。
如何自定义事件
自定义事件,也就是向监听器传递自己定义的事件类型,同时可以通过事件传递参数。
1.创建自定义事件名称的Event
dispatchEvent(new Event(“myEvnet”,true,false));
2.创建自定义事件类
Public class MyEvent extends Event{
….
}
dispatchEvent是EventDispatcher的方法:public function dispatchEvent(event:Event):Boolean将事件调度到事件流中。 事件目标是对其调用 dispatchEvent()
方法的 EventDispatcher 对象。
这句话就是说是哪个对象调用 dispatchEvent()
,那么该事件就会被分发到那个对象的事件流中,如果没有指明对象,那么默认为this对象,即应用程序。这时该事件被分发到应用程序对象的事件流中,而没有分发到特定对象的事件流中。一旦两个对象的不是父子关系(控件树),那么事件流不会在这两个对象之间有联系,那么事件不会被响应;如果是,则还是要响应。(这种情况dispatchEvent的参数Event对象的参数必须是三个,如上)。dispatchEvent就是说明有了新的事件,只要注册了该事件,就可以响应。
(这里的最后一段没怎么理解他要表达什么意思 ??)
http://www.cnblogs.com/BaiYong/archive/2009/08/17/1548025.html
next stone -->
AS、Flex的事件流学习笔记 <!-- t_title -->
不过,需要注意的是,捕获 的这个流向默认 情况下是处于关闭 状态的。另外,事件只在bubbles属性为true时才进行冒泡,可以冒泡的事件包括:change、click、doubleClick、keyDown、keyUp、mouseDown、mouseUp。
==============================
在以前ActionScript时代,比如我们要响应Button的Click事件,我们可以这样来写ButttonName.onRelease = function(){ //your code here};这是大多数人比较习惯的使用方式。并且具有一定的灵活性,不如: Button1.onRelease = Button2.onRelease = Button3.onRelease = function(){//your code here}。然而到了ActionScript3.0事情不像我们想得那么简单了,笔者我再最开始就很不适应,不过玩料几天后,不得不承认ActionScript3.0的处理机制药更好使用,更加OOP了
在ActionScript3.0中,对一个Button的事件处理方式是:
Button1.addEventlistener(MouseEvent.Press,MouseEventHandler);
private function MouseEventHandler(e:MouseEvent):void
{
//---------------Your code here-------------
}
但值得一提的是,这样的处理机制似乎更加具有灵活性,比如如果要给让一Sprite响应多个事件,我们可以这样做:
Sprite1.addEventlistener(MouseEvent.MOUSE_DOWN,MouseEventHandler);
Sprite1.addEventlistener(MouseEvent.MOUSE_PRESS,MouseEventHandler);
Sprite1.addEventlistener(MouseEvent.MOUSE_RELEASE,MouseEventHandler);
private function MouseEventHandler(e:MouseEvent)
{
Switch(e.type)
{
case "mouseDown" : //------Your code here-----;break;
case "mousePress" : //-------Your code here-----;break;
case "mouseRelease": //----Your code here------;break;
}
}
这样的一套处理方式将事件和组件类分开,并且不同的组件具有不同的响应事件,这样将很好的分离处理代码和Application代码。同时还具有弹性,请看下面的例子 如不您开发过ASP.NET,那么应该很清楚,一个Panel里面的所有Buttons,如果要响应事件,必须给每个Button添加事件处理程序。然而在Flex里面,您没有这样做的必要。比如您的一个ID为“canvas_buttons”的Canvas,里面放有3个Button,分别是Button1,Button2,Button3,现在您可以这样做
canvas_buttons.addEventlistener(MouseEvent.MOUSE_DOWN,MouseEventHandler);
private function MouseEventHandler(e:MouseEvent):void
{
switch(e.target.lable)
{
case "Button1" : //---------Your code here--------;break;
case "Button2" : //--------Your code here-------;break;
case "Button3" : //--------Your code here-------;break;
}
}
注意这里使用的是e.target,如果要精确e所对的容器是哪一个,要使用e.currentTarget。我想看了上面的这个例子也应该明白它们之间的区别了吧。 那么这样事件类全部继承与基类:Event,对于不同的组件会有不同的事件类来响应该组件事件,这样使比较灵活的。比如SliderEvent具有value属性,VideoEvent具有complete,ready属性。 同时我们在处理传递事件的组件的时候,我们并没有要知道组件名称的必要,我们唯一要知道的只是该对象是属于什么类别。我们可以用如下方式实现,比如我们知道是个Button,那么我们可以使用 var but:Button = Button(e.target)来实现。感觉像是偷的ASP.NET 里的Sender Object 似的 那么在Flex里面更让人觉得爽的地方就是事件响应后的反应机制。虽然在ActionScript2.0里面已经有EventDispatch类了,但是在具体使用的时候并不是很好使用的,您需要使用Initialize()方法来初始化。比较繁琐 在ActionScirpt3.0里面,将该方法removed,Felx的组件似乎都是继承自:UIComponent的(并没有全部察看过).而UIComponent继承自EventDispatcher,所以一般都具有dispatcher的方法,该方法可以更加灵活的操作事件。比如您可以拿着遥控器打开家里的烧水的炉子,然后您完全可以在水烧好后dispatche(new Event())来让炉子自动关闭。
http://www.hugo8.com/Article.Asp?ID=679
next stone -->
Event Flow(事件流)是ActionScript 3.0中处理事件响应的机制。事件对象创建后,被Flash Player分配给指定的目标事件。事件对象穿过Display List(显示架构)的每个层次,到达目标事件。有些情况下,事件对象会以“起泡”的方式按原路线返回。这个在Display List中往返的过程叫做Event Flow(事件流)。事件流描述了事件对象如何在Display List中移动。Event Flow从概念上可以分为三个阶段,分别如下。
* capture phase(获取阶段),这个阶段由Stage(舞台)上所有的目标结点的父结点组成。
* target phase(目标阶段),这个阶段由单独的目标结点组成。
* bubbling phase(起泡阶段),这个阶段由从目标结点的父结点返回到舞台的过程中相遇的结点组成。
组成Event Flow三个阶段的结点在display list中的结构,如图所示。
如果用户单击了子结点1,Flash Player会发派一个事件对象到事件流中,如图所示。这个事件对象的行程从Stage(舞台)开始,向下移动到目标结点的父结点,然后才移动到目标结点“子结点1”,然后通过“起泡”的机制返回Stage。在返回Stage的行程中再次经过其父结点。
并不是每个事件对象都参与事件流的三个阶段。有一些类型的事件,如enterFrame事件对象,被发派到目标对象的时候不参与获取和起泡阶段。另外还有一些事件对象,他们的目标对象不在display list中,这样的对象通过stock接口发派到目标对象,同样这样的事件对象不经过事件流的获取和起泡阶段。
http://www.diybl.com/course/4_webprogram/asp.net/asp_netshl/200855/114267.html