使用事件捕获和冒泡可以最大程度地减少事件处理函数。
ActionScript 3.0 中的事件模型引入了事件捕获和事件冒泡的概念。利用事件冒泡可帮助您优化 ActionScript 代码执行时间。您可以在一个对象(而不是多个对象)上注册事件处理函数以提高性能。
例如,想象创建这样一种游戏,在该游戏中用户必须以最快的速度单击苹果以将其销毁。该游戏将删除屏幕上各个被击中的苹果并为用户增加分数。要侦听由各个苹果调度的
MouseEvent.CLICK
事件,您可能会编写以下代码:
const MAX_NUM:int = 10;
var sceneWidth:int = stage.stageWidth;
var sceneHeight:int = stage.stageHeight;
var currentApple:InteractiveObject;
var currentAppleClicked:InteractiveObject;
for ( var i:int = 0; i< MAX_NUM; i++ )
{
currentApple = new Apple();
currentApple.x = Math.random()*sceneWidth;
currentApple.y = Math.random()*sceneHeight;
addChild ( currentApple );
// Listen to the MouseEvent.CLICK event
currentApple.addEventListener ( MouseEvent.CLICK, onAppleClick );
}
function onAppleClick ( e:MouseEvent ):void
{
currentAppleClicked = e.currentTarget as InteractiveObject;
currentAppleClicked.removeEventListener(MouseEvent.CLICK, onAppleClick );
removeChild ( currentAppleClicked );
}
此代码对各个 Apple 实例调用
addEventListener()
方法。此外,它还会在用户单击每个苹果时使用
removeEventListener()
方法删除对应的侦听器。然而,ActionScript 3.0 中的事件模型为某些事件提供了一个捕获和冒泡阶段,允许您侦听来自父 InteractiveObject 的这些事件。因此,可以优化以上代码并在最大程度上减少对
addEventListener()
和
removeEventListener()
方法的调用次数。以下代码使用捕获阶段侦听来自父对象的事件:
const MAX_NUM:int = 10;
var sceneWidth:int = stage.stageWidth;
var sceneHeight:int = stage.stageHeight;
var currentApple:InteractiveObject;
var currentAppleClicked:InteractiveObject;
var container:Sprite = new Sprite();
addChild ( container );
// Listen to the MouseEvent.CLICK on the apple's parent
// Passing true as third parameter catches the event during its capture phase
container.addEventListener ( MouseEvent.CLICK, onAppleClick, true );
for ( var i:int = 0; i< MAX_NUM; i++ )
{
currentApple = new Apple();
currentApple.x = Math.random()*sceneWidth;
currentApple.y = Math.random()*sceneHeight;
container.addChild ( currentApple );
}
function onAppleClick ( e:MouseEvent ):void
{
currentAppleClicked = e.target as InteractiveObject;
container.removeChild ( currentAppleClicked );
}
上述代码不仅经过了简化,而且在很大程度进行了优化,只对父容器调用了一次
addEventListener()
方法。侦听器不再注册到 Apple 实例,因此不需要在单击苹果时将其删除。可通过停止事件传播(此操作将阻止继续传播事件)来进一步优化
onAppleClick()
处理函数:
function onAppleClick ( e:MouseEvent ):void
{
e.stopPropagation();
currentAppleClicked = e.target as InteractiveObject;
container.removeChild ( currentAppleClicked );
}
冒泡阶段也可用于捕捉事件,方法是将
false
作为第三个参数传递到
addEventListener()
方法:
// Listen to the MouseEvent.CLICK on apple's parent
// Passing false as third parameter catches the event during its bubbling phase
container.addEventListener ( MouseEvent.CLICK, onAppleClick, false );
捕获阶段参数的默认值是
false
,因此您可以将其忽略:
container.addEventListener ( MouseEvent.CLICK, onAppleClick );