事件机制的三个阶段

AS3 事件流分三个阶段 :
1. 捕获阶段 ( 即由根节点流向子节点 , 检测每个节点是否注册了监听器 )

2.目标阶段 (激发在目标对象本身注册的监听程序)

3.冒泡阶段 (从目标节点到根节点,检测每个节点是否注册了监听器)。事件流在此阶段触发

 

当中涉及了两个属性targetcurrentTarget,target是事件的派发者,currentTarget是正在检测的对象,当开始了事件流,事件的currentTarget属性处于不断变化中.(下面第二段代码详细说明)

PS:注册事件时捕获阶段默认是关闭的,无论事件是否开启了捕获,事件流只会两选一去执行注册的监听程序.

 

关于EventDispatcher三个函数的参数:

1.addEventlistener(事件类型,监听函数,是否打开捕获阶段,监听器优先级别,是否打开弱监听)

2.removeEventListener(事件类型,监听函数,是否打开捕获阶段) (前两个参数是必须的,如果注册监听器时打开了捕获阶段,那么第三个参数也是必须的,否则会出现错误)

3.dispatchEvent(new Event(事件类型,是否冒泡,是否可以取消事件))

 

关于Event扩展有两点要注意:

 1.可以定义字符串常量代表事件类型.

2.构造函数必须调用父类的构造函数,super(type,bubbles,cancelable)

3.扩展Event可以使Event带自定义变量,从而可以传递数据.

 

以下来自:http://bbs.blueidea.com/thread-2909457-1-1.html  秋色烽火

 

AS3的 事件流就三个阶段,捕获 > 目标 > 冒泡
而在鼠标事件中,共有10种鼠标事件,分别如下:
点击事件
: MouseEvent.CLICK ,MouseEvent.DOUBLE_CLICK
按键事件: MouseEvent.MOUSE_DOWN ,MouseEvent.MOUSE_UP
悬停事件: MouseEvent.MOUSE_OVER ,MouseEvent.MOUSE_OUT ,MouseEvent.ROLL_OVER ,MouseEvent.ROLL_OUT
移动事件: MouseEvent.MOUSE_MOVE
滚轮事件: MouseEvent.MOUSE_WHEEL

最令我不解的就是
悬停事件: MOUSE_OVER  ,MOUSE_OUT  ,ROLL_OVER  ,ROLL_OUT

它们的具体工用是相似的
MOUSE_OVER = ROLL_OVER  
MOUSE_OUT = ROLL_OUT

唯一不同的是前者参与事件流的冒泡阶段,而后者则不参加
,
黑羽书上的例子类似,一个内部有文本框的按钮
,
MOUSE_OVER  ,MOUSE_OUT
事件中,鼠标移到按钮上,会触发over事件,当鼠标继续移,移到按钮里的文本上时
,
就会触发文本的MOUSE_OVER事件,同一时间,按钮的MOUSE_OUT事件也会触发

而如果使用ROLL_OVER ,ROLL_OUT,这种情况下,鼠标移入按钮后,只要不移出按钮范围,按钮的OUT事件是不会触发的.

(_______
//
括号内的内容为后期补充,实然是最终结果,建议先跳过看后面的,回头再看本段文字
此处我掉入了一个误区,不明白为什么移上子mc会触发移出事件,然后又触发移入事件,
其实不然,是事件流的原因,因为事件流机制默认是在冒泡阶段侦听的

所以整个流程解析就是,
1.
先是鼠标移入按钮范围,触发按钮mc
MOUSE_OVER事件,向上冒泡,没有其它对象侦听了,
2.
鼠标继续移,移入内部影片剪辑a的范围时,触发mc
MOUSE_OUT事件,同时又触发aMOUSE_OVER事件,
3.
进入子影片剪辑a的冒泡阶段,因为a的父对象mc有侦听
MOUSE_OVER事件的,所以会触发mc的移入事件
4.
鼠标移出a影片剪辑范围(仍未移出mc范围),触发a侦听的MOUSE_OUT事件,
5.
进入子影片剪辑a的冒泡阶段,触发mc的移出事件
MOUSE_OUT
6.
鼠标重新移入到mc影片剪辑的范围,触发mcMOUSE_OVER事件
7.
鼠标移出mc范围,触发mcMOUSE_OUT事件
//鼠标移入mc范围,未移入子影片剪辑a范围
//
外部_移入_当前 mc _目标 mc mcMOUSE_OVER生效
//鼠标移入子影片剪辑a范围
//
外部_移出_当前 mc _目标 mc mcMOUSE_OUT生效
//
内部_移入_当前 a _目标 a   mc.aMOUSE_OVER生效
//
外部_移入_当前 mc _目标 a  冒泡阶段,mcMOUSE_OVER生效

//
鼠标移出子影片剪辑a范围
//
内部_移出_当前 a _目标 a   mc.aMOUSE_OUT生效
//
外部_移出_当前 mc _目标 a  冒泡阶段,mcMOUSE_OUT生效
//
外部_移入_当前 mc _目标 mc mcMOUSE_OVER生效
//
鼠标移出影片剪辑mc范围,回到舞台
//外部_移出_当前 mc _目标 mc  mcMOUE_OUT生效



上面是trace出来的结果,下面是源代码,场景中一个大影片剪辑mc,套一个小影片剪辑a

复制内容到剪贴板

代码:

mc.a.addEventListener(MouseEvent.MOUSE_OVER,onFunA)
mc.a.addEventListener(MouseEvent.MOUSE_OUT,onFunB)
mc.addEventListener(MouseEvent.MOUSE_OVER,onFunC)
mc.addEventListener(MouseEvent.MOUSE_OUT,onFunD)
function onFunA(_evt:MouseEvent){
trace("
内部_移入_当前",_evt.currentTarget.name,"_目标",_evt.target.name)
}
function onFunB(_evt:MouseEvent){
trace("
内部_移出_当前",_evt.currentTarget.name,"_目标",_evt.target.name)
}
function onFunC(_evt:MouseEvent){
trace("
外部_移入_当前",_evt.currentTarget.name,"_目标",_evt.target.name)
}
function onFunD(_evt:MouseEvent){
trace("
外部_移出_当前",_evt.currentTarget.name,"_目标",_evt.target.name)
}

________________________________)
因为displayObjectDisplayObjectContainer(容器)对象有一个属性mouseChildren,控制子显示对象是否接受事件,一般看到上面的话,而又知道mouseChildren属性的朋友,就会有疑问了(包括刚才的我),那这样我设显示对象的mouseChildren属性为false不就可以避免MOUSE_OUT事件在按钮内部触发了吗?
对了,这点黑羽在最后说明白了,在某些情况下,我们需要在子显示对象上写事件的,如果设了mouseChildrenfalse,则很不方便了.

最后,我对事件的冒泡过程不太明确,自己写了个小测试来验证了.在场景中再一个矩形影片剪辑,实例名mc 双击进入后,一个矩形(稍小的),做成影片剪辑,实例名a
这样做成了一个父子套的关系,
然后写代码

复制内容到剪贴板

代码:

mc.a.addEventListener(MouseEvent.CLICK,onFunA)
mc.addEventListener(MouseEvent.CLICK,onFunB)
function onFunA(_evt:MouseEvent){
trace(_evt.currentTarget.name,"_",_evt.target.name)
}
function onFunB(_evt:MouseEvent){
trace(_evt.currentTarget.name,"_",_evt.target.name)
}

运行,在单纯mc的范围上单击,返回的targetmc,currentTarget也是mc
输出结果:
mc _ mc
而如果鼠标再移入一点,a影片剪辑上单击的时候,
事件流先到达目标阶段,触发a的侦听,然后冒泡阶段,再到mc
所以target一直是a,currentTarget目标会在两次触发中分别为a(内层)mc(外层)
输出结果:
a _ a
mc _ a
上面这个实验就是想证明自己的一个想法,冒泡事件是否触发的顺序是从底到顶的,上面的输出证实了这点理解.

这里可以返回上面看括号里的内容了,看完再接下面这段总结

总结:
1.
事件流是面向DisplayObject的一个过程机制,但凡显示对象触发的事件,必有这个流过程,自上而下,再自下而上
2.
事件流机制是在同一条路径上的父子关系的显示对象都会参与的(默认)
3.
参与事件流的对象,对内部子对象,同样会触发MOUSE_OUT事件的
4.
最重要的一点就是,子对象触发的事件,只要父对象有侦听,那么无论如何,父对象都会触发一次所侦听的事件
而且顺序是子对象先触发事件,然后父对象再触发(这是由冒泡阶段的顺序触发的)
5.addEventListener函数中的第三个参数设为true,则只在捕获阶段侦听,对于没有子对象的元素,事件是不会触发的,只有当子对象同样侦听相同事件时,才会触发事件(因为没有目标阶段)
反正要理解事件机制,三个阶段的执行顺序及执行因素理解好后,下面的原理就很好理解了
如果设置addEventListener函数的第三个参数为true,会中断目标阶段的检测,但它始终会参加事件流,
所以ROLL_OVERROLL_OUT是实现不参加事件流(捕获和冒泡均不参加)操作的方法

 

 

 

 

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值