ActionScript3.0事件机制
学习as3.0有几个月了,一直崇拜其强大的事件机制,很久之前就已经有整理as3.0事件机制的概要与其用法,经过几天的准备,整理和参考其他资料,今天就把其整理出来!
(一)、概述:
1.所有的事件必须都要继承自Event这个类(全饰名称flash.events.Event)否则,事件发送就不能成功发送,也就是说,在使用事件之间,需导入flash.events.Event包。
2.事件声明的语法:事件目标.addEventListener(事件类型,侦听器)(常用);
3.事件流:捕获阶段+目标阶段+冒泡阶段。注意:e.eventPhase正整数,表示事件响应的阶段。不是所有的事件都有这三个阶段。如 Timer、URLLoader。具体详细的稍后再分析
4.事件注册:事件目标.addEventListener(事件类型,侦听器,useCaptrue);useCaptrue=true:只对捕获阶段产生作用 ,useCaptrue=false:只对目标和冒泡阶段产生作用。默认是false,另外还有一些可选参数,一般 不常用到,也不详细说了。具体声明格式如下:
事件目标.addEventListener(事件类型,侦听器,useCapture:Boolean=false,priority:int=0,useWeakReference:Boolean=false)
5.获取当前事件对象:e.currentTarget与e.target。
(二)、详细分析:
1.事件阶段:之前说,不是所有事件都有:捕获阶段、目标阶段和冒泡阶段这三个阶段,如 Timer、URLLoader。因为某些事件它们的事件对象将直接派送给目标对象(target).它们只包含目标阶段而没有捕获阶段和冒泡阶段。它们不会像显示对象容器 (DisplayObjectContainer)那样有可能被一个DisplayObjectContainer对象包含或者自己包含一个 DisplayObjectContainer对象,它们往往是单独存在的。也就是说如果一个显示对象不在显示列表中时,FlashPlaye会把事件直 接派送给它,这个时候就没有事件流,也没有捕获阶段和冒泡阶段,只有目标阶段。所以不是所有的事件都有三个阶段的。
2.事件流:首先看一幅图(摘自网上as3.0事件流分析)

(1).图中假定的事件派发的对象是子节点1,从图中我们可以看出,事件流并没有经过子节点2,也就是说如果在子节点2中监听事件,那子节点2是无法监听得到事件的。那么如何在子节点2监听子节点1的事件呢?办法有很多种,最常用就是向子节点1与子节点2都传入一个相同的对象的实例,在子节点1中用这个对象实例发出事件,在子节点2中用这个对象实例监听事件(在目标阶段捕获事件)。这样就可以收到字节点1的事件了。
(2).图中,如果父节点监听到子节点1 的事件,有两种方法可以监听得到:
1).自定义事件。自定义事件有两种方法可以实现。
一种是在父节点里面用子节点监听事件(如子节点1.addEventListener(事件类型,侦听器)此时不需要设置addEventListener中的 useCapture参数和new Event时Event的bubbles参数。就可以直接监听到子节点1的事件,因为此时直接在目标阶段捕捉事件。
另外一种方法是直接用在父节点中加入addEventListener(事件类型,侦听器)可以监听子节点1的事件,但是前提条件是在父节点监听事件的时候要把 addEventListener中的useCapture参数设置成true(如 addEventListener(MenuEvent.MENU_Event, handler,true)或者字节点1中new Event时将Event的bubbles参数设置为true( new MenuEvent(MenuEvent.MENU_Event,true))否则,父节点是无法监听到子节点的事件。因为addEventListener中的useCapture的默认是false也就是侦听器只在目标或冒泡阶段处理事件,而new Event时将Event的bubbles参数default也是false也就是说不参与事件流的冒泡阶段。如果不设置useCapture或者bubbles为true的话,那么父节点肯定无法监听到子节点的事件。
2).非自定义事件,如mouseEvent等本身自带的事件。如果是非自定义事件时,直接用在父节点中加入addEventListener(MouseEvent.CLICK, 监听器);就可以监听子节点1的事件。
(三)、注意点:
- 使用 EventDispatcher 对象注册事件侦听器对象,以使侦听器能够接收事件通知。可以为特定类型的事件、阶段和优先级在显示列表的所有节点上注册事件侦听器。
- 成功注册一个事件侦听器后,无法通过额外调用 addEventListener() 来更改其优先级。要更改侦听器的优先级,必须首先调用removeListener()。然后,可以使用新的优先级再次注册该侦听器。
- 注册该侦听器后,如果 继续调用具有不同type或useCapture值的addEventListener(),则会创建单独的侦听器注册。例如,如果首先注册useCapture 设置为 true 的侦听器,则该侦听器只在捕获阶段进行侦听。如果使用同一个侦听器对象再次调用 addEventListener(),并将useCapture 设置为false,那么便会拥有两个单独的侦听器:一个在捕获阶段进行侦听,另一个在目标和冒泡阶段进行侦听。
- 不能只为目标阶段或冒泡阶段注册事件侦听器。这些阶段在注册期间是成对出现的,因为冒泡阶段只适用于目标节点的始祖
- 复制 EventDispatcher 实例时并不复制其中附加的事件侦听器。(如果新近创建的节点需要一个事件侦听器,必须在创建该节点后附加该侦听器。) 但是,如果移动 EventDispatcher 实例,则其中附加的事件侦听器也会随之移动。
- 要养成调用 removeEventListener() 删除它的好习惯,当不再需要某个事件侦听器,需remove掉,否则会产生内存问题。由于垃圾回收器不会删除仍包含引用的对象,因此不会从内存中自动删除使用已注册事件侦听器的对象。
- 如果在正在处理事件的节点上注册事件侦听器,则不会在当前阶段触发事件侦听器,但会在事件流的稍后阶段触发,如冒泡阶段。
- 如果从正在处理事件的节点中删除事件侦听器,则该事件侦听器仍由当前操作触发。删除事件侦听器后,决不会再次调用该事件侦听器(除非再次注册以备将来处理)。
(四)、总结:as3.0的事件机制十分强大,Event内容也很多了。以后等我精通了高级内容时在提到如何运用吧。估计,要想玩转Flash,Event类必须很精通。呵呵。。。就此先写些心得和大家交流下吧。
浙公网安备 33010602011771号