Egret社区
1银子
本帖最后由 pyed 于 2014-8-16 15:55 编辑

开发时遇到一个问题,自定义的容器dispatchEvent一个事件,在主进程中收不到此事件。和http://bbs.egret-labs.org/thread-237-1-6.html是一样的情况。他的解决方法是在dispatchEvent中,讲bubles设置为true
于是去Event的源码查找了一下关于事件流和冒泡的信息,发现还是模模糊糊不明白
请问谁能介绍一下事件流的机制和冒泡的具体作用吗?

不胜感激!

最佳答案

查看完整内容

楼主应该是没有接触过 Flash 的事件机制,但是楼主对flash事件机制理解速度如此之快,真心令人佩服 关于楼主 “为什么 bubbles = false , useCapture = true” 无法监听到捕获事件的问题,可以这么解释 “bubbles = false ” 不是简单的理解为不冒泡,而是应该理解成不存在整个“捕获-目标-冒泡” 事件流,只有“目标” 这个阶段。 如果这样理解的话,楼主的疑惑应该就迎刃而解了 ...
分享到 :
3 人收藏

7 个回复

倒序浏览
Wander  官方团队 | 2014-8-15 22:07:12
pyed 发表于 2014-8-16 15:18
update 2014/8/16根据API文档:
Class: egret.EventDispatcher
addEventListener( type: string, listener ...

楼主应该是没有接触过 Flash 的事件机制,但是楼主对flash事件机制理解速度如此之快,真心令人佩服

关于楼主 “为什么 bubbles = false , useCapture = true” 无法监听到捕获事件的问题,可以这么解释

“bubbles = false ” 不是简单的理解为不冒泡,而是应该理解成不存在整个“捕获-目标-冒泡” 事件流,只有“目标” 这个阶段。

如果这样理解的话,楼主的疑惑应该就迎刃而解了
pyed  登堂入室 | 2014-8-15 22:08:19
自己顶一下
在源码中看到这样的注释:
*捕获阶段 (EventPhase.CAPTURING_PHASE)。
*目标阶段 (EventPhase.AT_TARGET)。
*冒泡阶段 (EventPhase.BUBBLING_PHASE)。
还是不知道这分别代表什么
guoshaorui  超级斑竹 | 2014-8-15 22:49:31
参见Flash中冒泡的说明:
http://www.cnblogs.com/zjhnl/archive/2012/05/23/2514841.html

Egret中也是同样的道理
pyed  登堂入室 | 2014-8-16 10:40:58
guoshaorui 发表于 2014-8-15 22:49
参见Flash中冒泡的说明:
http://www.cnblogs.com/zjhnl/archive/2012/05/23/2514841.html

十分感谢
pyed  登堂入室 | 2014-8-16 11:38:00
本帖最后由 pyed 于 2014-8-16 11:42 编辑

最后总结一下guoshaorui给的资料:
先贴一下flash官网中的相关概念,与egret同理:
×事件流
当显示列表上的对象(屏幕上显示的对象)发生事件时,将通知包括该对象在内的所有对象发生了此事件,并依次通知它们的事件侦听器。此过程从舞台开始,并在显示列表中一直进行到发生事件的实际对象,然后再返回到舞台。此过程称为事件流。
×事件目标
事件目标实际调度事件的对象。例如,如果用户单击位于 Sprite(位于舞台内)内的按钮,则所有这些对象将调度事件,但事件目标是指实际发生事件的对象,此处指单击的按钮。

就我这个问题中,我在stage上添加了一个主场景类,然后在这个类上添加了一个子场景,场景中有一个按钮,点击按钮后发出事件。同时,我在主场景类上添加了监听器,监听到事件以后removeChildren,并添加游戏场景类。 但是实际上写完以后,发现事件的确能成功发送,但是监听器没有办法收听到事件。
这里,事件目标是按钮。
实际上的内部过程是,按钮发送事件以后,会产生一个事件对象event,因为按钮在显示列表中,因此event会从舞台开始依次:舞台->主场景类->子场景类->按钮依次走一遭。也就是先经过捕获阶段和目标阶段,(但是阶段监听器也已经产生了吧,为什么主场景会收不到?不明白,求解答),如果不把bubbles=true,那么事件对象旅程就到此为止了。这样等到按钮收到这个事件之后,事件就消失了。于是作为父父场景的主场景类就收不到事件了。otherwise, 如果把冒泡阶段打开,事件结束目标阶段后会往返进入冒泡阶段,即从按钮到stage,这样的话,主场景类便可以收到事件了。
当事件目标不在显示列表中,则事件直接调度给事件目标,没有进入这个事件流,也就是另一套机制了
pyed  登堂入室 | 2014-8-16 15:18:41
update 2014/8/16根据API文档:
Class: egret.EventDispatcher
addEventListener( type: string, listener: Function, thisObject: any, useCapture: boolean, priority: number )

useCapture   boolean
确定侦听器是运行于捕获阶段还是运行于目标和冒泡阶段。如果将 useCapture 设置为 true, 则侦听器只在捕获阶段处理事件,而不在目标或冒泡阶段处理事件。如果 useCapture 为 false,则侦听器只在目标或冒泡阶段处理事件。 要在所有三个阶段都侦听事件,请调用 addEventListener 两次:一次将 useCapture 设置为 true,一次将 useCapture 设置为 false。


于是进行了以下尝试:将dispatchEvent中bubbles=false, 讲addEventListener中useCapture=true,发现仍然无法监听到事件。这是否说明,在事件对象抵达事件目标之前,父节点都没有办法监听到事件呢? 不知道,也许是我想太多

pyed  登堂入室 | 2014-8-16 17:10:39
本帖最后由 pyed 于 2014-8-16 17:13 编辑
Wander 发表于 2014-8-15 22:07
楼主应该是没有接触过 Flash 的事件机制,但是楼主对flash事件机制理解速度如此之快,真心令人佩服

关于 ...

Wander桑,超级感谢,完全解决了疑问

给其他新人整理一下完整的解答索引:
1.事件流过程入门:首先请看guoshaorui给出的链接
2.事件流、事件目标和冒泡入门:请查看6楼我关于该链接资料的整理说明
3.具体关于捕获阶段和冒泡阶段的事件流疑问:请看我在7楼的update
4.关于3的解答:请看最佳答案-Wander给出的关于冒泡过程的解答。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|京网文[2014]0791-191号|京ICP证150115号|Egret社区 ( 京ICP备14025619号 )

Powered by Discuz! X3.4 © 2001-2019 Comsenz Inc.

返回顶部