이벤트 캡처 및 버블링

이벤트 캡처 및 버블링을 사용하여 이벤트 핸들러를 최소화할 수 있습니다.

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 );