Захват и цепочки событий позволяют уменьшить количество обработчиков событий.
В модели события 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 );
}
Фазу захвата можно также использовать для перехвата события. Для этого нужно передать методу
addEventListener()
значение
false
в качестве третьего параметра.
// 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 );