事件捕捉和反昇

使用事件捕捉和反昇可最小化事件處理常式。

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