21.9.1. 事件侦听器列表的改变
如我们刚刚所学的,当一个给定的事件发生时, ActionScript根据预先定好的事件流来通知适当
的对象。按照顺序当每一个对象接收到事件通知,它的事件侦听器就会被调用。这个被给定事件通
知调用特殊的侦听器列表在事件通知发出之前就被决定了。一旦通知开始,侦听器列表无法更改。
比如,考虑一个目标为Sprite 对象的一个MouseEvent.CLICK 事件派送,这个Sprite 对象在
Stage 实例上。那么事件流由3个事件通知组成:
CAPTURE PHASE: (1) Stage object notified
TARGET PHASE: (2) Sprite object notified
BUBBLING PHASE: (3) Stage object notified
假设,在第一步通知阶段(1),Stage 侦听器函数里的代码注册了一个新的MouseEvent.CLICK 侦
听器在Sprite 对象上。由于这个事件还没有传播到Sprite 对象,这个心的侦听器会在第二通知阶段
(2)被调用。
进一步假设,在第一步通知阶段 (1),Stage 侦听器中的代码注册了一个新的MouseEvent.CLICK
侦听器在Stage 实例的冒泡阶段上, 由于第一步通知(1)已经开始了, Stage 实例的侦听器列表已
经被冰封,所以新的侦听器不会在第一步通知阶段(1)调用. 但是,新的侦听器会在后续的事件流中
在冒泡阶段(3)被调用.
最后,假设在第二部阶段 (2),Sprite 侦听器中的代码从Sprite注销了一个已经存在的
MouseEvent.CLICK侦听器,由于在第二通知阶段(2)已经开始,它的侦听器列表已经被冰封,所
以被移除的侦听器仍然会在第二通知阶段被调用。当然,如果另一个MouseEvent.CLICK 事件侦
听器被移除了,这个被移除的侦听器就无法被调用。
NOTE
在一个给定事件派送的任何点,当前阶段的被调用侦听器的列表都无法更改,但是事件流后续阶段
将被调用的侦听器的列表可以更改。
21.10. 自定义事件与事件流
ActionScript层级事件系统适用于所有的目标为显示对象的事件派送,即使这些事件派送是被程序
员手动派送的。当一个目标是处于显示层级的对象的自定义事件被发送,这个对象的父级对象就会
收到这个事件的通知。
Example 21-5 的代码证明了自定义事件也可以同内置事件一样在事件流中传播。在这个例子中,
一个测试类,CustomEventDemo 命令 ActionScript 发送一个自定义事件,事件的目标是一个处
于显示列表的Sprite 对象
Example 21-5. 一个自定义事件通过事件流派送
作为响应Example 21-5中的dispatchEvent()的调用, ActionScript 发送一个
CustomEventDemo.SOME_EVENT 事件进入事件流,目标为sprite. 这个事件流如下:
在捕获阶段, CustomEventDemo.SOME_EVENT 事件从Stage 实例开始往CustomEventDemo
对象传播。在目标阶段,事件传播给Sprite 对象。最后。在冒泡阶段,事件又传回给
CustomEventDemo 对象然后返回到Stage实例。当Stage 实例在冒泡阶段收到事件通知,
someEventListener() 会被调用,即使CustomEventDemo.SOME_EVENT是一个自定义事件,它
任然通过事件流传播.
同内置事件一样, ActionScript的层级事件构筑式样有助于自定义事件的代码集中化。比如,假设
我们创造了一个在线订购系统,具有一个购物篮部件,它包含了可选择的产品按钮。这个购物篮部
件是一个自定义类ShoppingBasket的实例。同样地,每一个产品按钮是一个自定义类Product.的
实例。Product 实例是ShoppingBasket 实例的可视化子级。ShoppingBasket 实例有一个标题栏
显示了当前被选中的产品名。
当用户选中一个产品按钮后,应用程序发送一个自定义事件Product.PRODUCT_SELECTED,目标
是对应的Product 实例。由于ShoppingBasket 实例是所有Product实例的父级,每当
Product.PRODUCT_SELECTED 事件发送时它都收到通知。因此,要保证ShoppingBasket 市里
的标题栏于选择的产品相吻合,我们只需要注册一个Product.PRODUCT_SELECTED侦听器在
ShoppingBasket 实例上。当productSelectedListener()被调用,我们就知道一个产品已经被选
择,所以我们更新购物篮的标题栏上的产品名称。
Example 21-6 和Example 21-7 战士了ShoppingBasket 类和Product 类. 代码注释会指导你。
于事件相关的部分标注粗体.
Example 21-6. ShoppingBasket 类
Example 21-7 展示了Product 类的代码.
Example 21-7. Product class
Example 21-8 提供了一个非常简单的应用程序来证明ShoppingBasket 和Product 类的基本用
法
Example 21-8. ShoppingBasket 演示
21.11. On to Input Events
我们已经学习了几乎所有的有关AS层级事件系统的代码工作,在下一章我们会把理论知识反倒实
践中,通过我们学习FP内置用户输入事件__