2011
09.29

as3 事件流机制的解释

通俗一点说吧

房子里面 有 冰箱

冰箱里面有饭盒

饭盒里面有食物

你可以理解成flash画面上的平面显示,也就是三层内嵌结构 Sprite嵌Sprite 再嵌Sprite

当你用鼠标在 食物上点击的时候

FlashPlayer就会沿路径向下寻找 这个过程叫做 捕获阶段,这个过程会走过 房子 冰箱 饭盒

第二步是目标阶段 即已经找到 食物了

第三步是冒泡阶段 FlashPlayer会沿原路向上回索 走的顺序是 饭盒 冰箱 房子

你可以理解成 捕获阶段是找出从顶级stage到目标食物之间的所有父子级包含关系

然后 找到目标了 ,携带着目标所发出的事件对象,

再根据捕获阶段找到的路 ,往回走,看看到底有哪些父级对象侦听了目标所发出的事件类型

上面的明白了 那你就很容易理解 target 和 currentTarget的区别了

target 就是目标对象 currentTarget 在事件流(冒泡阶段)中是不断变化的,依据是当时冒泡冒到哪一级对象

比如一个影片剪辑MC 里面有一个文本框TextField的话,我们为MC赋了侦听事件的话,

如果当时点击的范围在文本框上的话,target会指向这个文本框 而非添加侦听的MC,
在事件发生之初 ,即在目标阶段时 traget == currentTarget的
但因为会有冒泡事件 ,所以在事件冒泡到上级MC的时候,currentTarget 就等于MC了

但在整个事件流过程中,target是不变的 ,则哪一个显示对象发生的 ,target永远就是那个对象

最后我们再来看看相关的API知识

public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

我们平时用到的addEventListener其实它后边是有5个参数的 ,其中第一 第二个是最常用的 必须指定的参数,其它3个可根据情况使用 所以有默认值

type:即平时那些 MouseEvent.MOUSE_DOWN 之类的, 要侦听的事件类型
listener:即事件的处理函数

useCapture:设置事件侦听的阶段,因为事件流机制是分成三个部分的 捕获 目标 冒泡 ,这个函数默认不指定是false ,即运作于 冒泡阶段的

有时候我们希望父级的侦听先于目标对象,即在捕获阶段就触发父级对象的侦听事件,就可以指定这个参数为true了,否则不指定就是false值

addEventListener(MouseEvent.MOUSE_DOWN, func_mouseDown , true)

后边两个参数不常用 第一个是设置事件的优先级 在多个事件同级的情况下 这个设置执行优先级
第二个是设置处理函数的弱引用 , 即 上面的 func_mouseDown ,是基于AVM2的内存清理机制 一般极少使用 不详释

另外 再补充两个属性的说明

显示对象中

InteractiveObject – DisplayObject – EventDispatcher – Object

可接受鼠标键盘的交互对象,它是有一个属性,名字是:mouseEnabled

前边已经说了,as3的显示列表 事件机制是 基于事件流的

比如有时候 我们为子级和父级都侦听了事件 addEventListener ,但突然有需要屏蔽父级的事件侦听

我们不可能每次都去removeEventListener的,这时候我们就可以通过设置父级的mouseEnabled = false ,来临时屏蔽父级对象的事件侦听,需要的时候 mouseEnabled = true就可以马上重新侦听事件

另一个属性是 mouseChildren ,这个属性是影响子级对象的

比如我们平时如果事件处理中用到target的话, 比如我想用一个影片剪辑MC来做按钮的话

前面已经说过了 如果里面有文本的话,点击的时候 侦听事件中的traget有可能会指向这个TextField, 而非上级的MC,这样的话,就容易出错了

如果我们不想发生这样的错误 ,就可以设置 MC的 mouseChildren = false

來屏蔽子级对象的事件发生 ,即事件流过程,最后一级到达 MC 就不会再向下遍历的了

在这一级就马上转入目标阶段 转而再进入冒泡阶段

暂无回复

添加回复