[心得] AS3的事件传递机制

楼主: cochiachang (蓝玥)   2013-08-30 19:30:49
网志图文好读版: http://ppt.cc/sygC
=============================================
当事件被发送出来之后。Event一般来?都会有一个Flow。 Flow分三个部分:
Capture(捕获阶段)
Targeting(目标阶段)
Bubbling(冒泡阶段)
其关系图如下:
http://claire-chang.com/wp-content/uploads/2013/08/efAzj.jpg
值得一提的是,在FLASH里,只有和UI相关的物件
会有上图所示的目标及补获阶段的事件流,
一般像是Timer、Loader事件,是直接进入目标阶段,并不会有下图所示的事件流的流程。
在宣告Event时,也可以先指定事件是否要完整的跑完全部的流程。
var event:Event = new Event(type, bubbles, cancelable);
参数说明(官方文件)
type:String是要发送的事件的识别名称EX:Event.COMPLETE
bubbles:Boolean默认值是false,这个值是用来设定是否要有冒泡阶段,
如果传false,代表他不会跑完全部的流程,只会从Capture到target阶段就停止。
cancelable:Boolean默认值是false,
这个值是用来设定是否这个事件可以被event.preventDefault();取消,
如果设定为true的话,代表此事件是可以被取消的
(稍候在dispatchEvent会更详述这部份)。
常用的可以取消的事件有(cancelable为true):
FocusEvent.MOUSE_FOCUS_CHANGE
FocusEvent.KEY_FOCUS_CHANGE
TextEvent.TEXT_INPUT。
而发送事件则是用这一段程式码:
var result:Boolean = box.dispatchEvent(event);
在发送事件时,要注意,假使今天我们是在STAGE里面有一个box物件,
那当我们用box.dispatchEvent(event);
即使事件是用box发送的,事件还是会从stage > root > box这样跑。(请见上图)
假如在建立Event时,bubbles设为true,
那在上图跑的流程为stage > root > box > root > stage。
而若bubbles设为false,跑的流程则是stage > root > box
当我们用root.dispatchEvent(event);时
bubbles设为true,上图跑的流程为stage > root > stage
bubbles设为false,流程为stage > root
由此可知,事件流只会到目标(Target),就会停止往下传。
假如今天box里面有一个物件button,若是用box.dispatchEvent(event),
button物件是不会接到事件流的。(因为到目标阶段便会开始bubbles或停止)
并且假如今天root里同时有box和box2两个物件,
假使我们用box.dispatchEvent(event),则box2也不会接到事件。
至于第三个在建立Event的参数cancelable,不论值是true或false,
都不会影响事件流的流程。
那他的作用是做什么的呢?
我们可以发现,dispatchEvent有回传一个布林值,
cancelable就是在影响这个布林值的传回参数。
今天我们假如要创建一个物件,
但是要让使用者有权力去阻止这个事件发生后的后续发展时,可以这样写
if(this.dispathEvent(event)){
trace("success!");
//在这写后续发展
}
假使使用者在监听的途中呼叫 event.preventDefault();,
并且EVENT的cancelable为true时,dispatchEvent回传的值就会是false,
便不会执行trace("success!");那块区块。
但假使EVENT的cancelable为false时,
不论你在事件执行中有没有呼叫event.preventDefault(),
dispatchEvent回传的值就会是true。
一般我们会在传递事件的途中,去将事件拦截下来。增加监听事件的程式码如下
box.addEventListener(MouseEvent.MOUSE_DOWN,parent1Event);
官网关于addEventListener的说明如下
addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
传入的参数意义如下:
type(String):事件名称
listener(Function):要执行的Function
useCapture(Boolean):这个和本篇要说的事件流有关,当今天传入的值为true,
则只能在补获阶段去抓取事件,在冒泡阶段是听不到的。
如果将 useCapture 设置为 true,则侦听器只在捕获阶段处理事件,
而不在目标或冒泡阶段处理事件。如果 useCapture 为 false,
则侦听器只在目标或冒泡阶段处理事件。
要在所有三个阶段都侦听事件,需注册 addEventListener 两次:
一次将 useCapture 设置为 true,一次将 useCapture 设置为 false。
不过要注意的是,当今天若useCapture为true时,并不会听到target阶段时的事件,
但若为false时,也可以听到target阶段时的事件。
假使今天我们用box.dispatchEvent(event);来发送事件,
然后box的监听事件的useCapture设为true。
ex : box.addEventListener(MouseEvent.CLICK, rootClick, true);
这样rootClick事件并不会被呼叫到。
若box的监听事件的useCapture设为false 。
ex : box.addEventListener(MouseEvent.CLICK, rootClick, false);
这样rootClick事件便会被呼叫到。
priority(int):若今天同时有很多个监听器同时监听同一事件,
可用这个值来设定那一个监听器应该被优先执行。
数字愈高代表会愈快执行该事件侦听程式。
useWeakReference(Boolean):是否使用弱关连。
若是用弱关连,当被监听的物件所指到的变量被指向内存的其他地方,
这个关系也会一并被取消(物件会被GC回收)。
但如果传进的值是false,当今天被监听的物件的其他关连被指向别处时,
该物件不会被GC回收,需要手动removeEventListener时,该物件才会被GC回收。
除了上述的几个参数外,还有几个函数可以中断事件流的流程。
那就是stopPropagation()和stopImmediatePropagation()
这两个可以停止事件流继续下去。
那这两个函数有什么差别呢?
下图可以很清楚的解释差异:
stopPropagation():会把同一阶层的其他事件跑完才停止。
图: http://claire-chang.com/wp-content/uploads/2013/08/5MYe3.jp
stopImmediatePropagation():立刻停止之后所有的事件流。
图: http://claire-chang.com/wp-content/uploads/2013/08/jleAX.jpg
假如今天box同时有两个监听函数如下
box.addEventListener(MouseEvent.MOUSE_DOWN,eventMouseDownHandler1,false,1);
box.addEventListener(MouseEvent.MOUSE_DOWN,eventMouseDownHandler2,false,2);
则由于priority值的关系,
eventMouseDownHandler2 会先被执行,
eventMouseDownHandler1 在之后才被呼叫。
那若是在eventMouseDownHandler2里面呼叫event.stopPropagation(),
eventMouseDownHandler1还是会被执行才将事件流中断。
但是若在eventMouseDownHandler2里面呼叫event.stopImmediatePropagation(),
则eventMouseDownHandler1就不会被呼叫到了
网志好读版: http://claire-chang.com/1054-as3的事件传递机制
延伸阅读:
hasEventListener()与willTrigger()区别
http://ppt.cc/sqKU
作者: onchin (炸虾猪排丼)   0000-00-00 00:00:00
FLASH新手 虽然只看得懂前面一小段也获益良多@@ 推~
作者: viceversa56 (姊超猛)   2013-08-30 21:51:00
好久不见的心得文 推推
作者: lulu7953 (lulu)   2013-08-30 23:30:00
认真推~
作者: newton510 (~~~)   2013-08-31 16:05:00
好文~ 推~~
作者: BIAN (shu)   2013-09-11 10:02:00
推一个

Links booklink

Contact Us: admin [ a t ] ucptt.com