Sättet på vilket avlyssnarfunktioner skapas i ActionScript 3.0-händelsemodellen uppvisar vissa avvikelser från DOM-händelsemodellen. I DOM-händelsemodellen finns det en klar skillnad mellan en händelseavlyssnare och en avlyssnarfunktion: en händelseavlyssnare är en instans av en klass som implementerar EventListener-gränssnittet, medan en avlyssnarfunktion är en metod i den klassen med namnet handleEvent(). I DOM-händelsemodellen registrerar du klassinstansen som innehåller avlyssnarfunktionen snarare än den faktiska avlyssnarfunktionen.
I ActionScript 3.0-händelsemodellen är det ingen skillnad på en händelseavlyssnare och en avlyssnarfunktion. ActionScript 3.0 har inte något EventListener-gränssnitt, och avlyssnarfunktioner kan definieras utanför en klass eller som del av en klass. Dessutom behöver avlyssnarfunktioner inte heta handleEvent(). De kan namnges med valfri, giltig identifierare. I ActionScript 3.0 registrerar du namnet på den faktiska avlyssnarfunktionen.
Avlyssnarfunktion definierad utanför en klass
Nedanstående kod skapar en enkel SWF-fil som visar en röd kvadrat. En avlyssnare med namnet clickHandler(), som inte ingår i någon klass, lyssnar efter musklickningshändelser som sker i den röda rutan.
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
}
function clickHandler(event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
När en användare interagerar med den slutliga SWF-filen genom att klicka på rutan, genererar Flash Player eller AIR följande spårningsutdata:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Observera att händelseobjektet överförs som ett argument till clickHandler(). Detta gör att din avlyssnarfunktion kan undersöka händelseobjektet. I det här exemplet använder du händelseobjektets type-egenskap för att kontrollera om händelsen är en klickningshändelse.
Exemplet kontrollerar även värdet för nyckelordet this. I det här fallet representerar this det globala objektet, vilket är rimligt eftersom funktionen har definierats utanför en anpassad klass eller objekt.
Avlyssnarfunktion definierad som en klassmetod
Följande exempel är identiskt med föregående exempel som definierar klassen ClickExample, men här definieras funktionen clickHandler() som en metod i klassen ChildSprite:
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, clickHandler);
}
private function clickHandler(event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
}
När en användare interagerar med den slutliga SWF-filen genom att klicka på den röda rutan, genererar Flash Player eller AIR följande spårningsutdata:
clickHandler detected an event of type: click
the this keyword refers to: [object ChildSprite]
Observera att nyckelordet this refererar till ChildSprite-instansen med namnet child. Detta beteende skiljer sig från det i ActionScript 2.0. Om du använde komponenter i ActionScript 2.0 kanske du kommer ihåg att när en klassmetod överfördes till UIEventDispatcher.addEventListener(), kopplades omfånget på metoden till komponenten som sände händelsen i stället för till klassen i vilken avlyssnarmetoden definierades. Så om du använde den här tekniken i ActionScript 2.0 skulle nyckelordet this referera till komponenten som sänder händelsen i stället för till ChildSprite-instansen.
Det här var till nackdel för vissa programmerare, eftersom det innebar att de inte kunde få tillgång till andra metoder eller egenskaper för klassen som innehöll avlyssnarmetoden. För att komma runt problemet kunde ActionScript 2.0-programmerare använda klassen mx.util.Delegate för att ändra omfånget på avlyssnarmetoden. Detta är nu inte längre nödvändigt, eftersom ActionScript 3.0 skapar en bunden metod när addEventListener() anropas. Det innebär att nyckelordet this refererar till ChildSprite-instansen med namnet child, och programmeraren får tillgång till de andra metoderna och egenskaperna i klassen ChildSprite.
Händelseavlyssnare som inte bör användas
Det finns en tredje teknik som kan användas för att skapa ett generiskt objekt med en egenskap som pekar på en dynamiskt tilldelad avlyssnarfunktion, men det här är inte en teknik som rekommenderas. Den beskrivs bara här för att den ofta användes i ActionScript 2.0. Den bör inte användas i ActionScript 3.0. Den här tekniken rekommenderas inte eftersom nyckelordet this kommer att referera till det globala objektet i stället för till avlyssnarobjektet.
Följande exempel är identiskt med föregående exempel från klassen ClickExample förutom att avlyssnarfunktionen definieras som en del av ett generiskt objekt med namnet myListenerObj:
package
{
import flash.display.Sprite;
public class ClickExample extends Sprite
{
public function ClickExample()
{
var child:ChildSprite = new ChildSprite();
addChild(child);
}
}
}
import flash.display.Sprite;
import flash.events.MouseEvent;
class ChildSprite extends Sprite
{
public function ChildSprite()
{
graphics.beginFill(0xFF0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
addEventListener(MouseEvent.CLICK, myListenerObj.clickHandler);
}
}
var myListenerObj:Object = new Object();
myListenerObj.clickHandler = function (event:MouseEvent):void
{
trace("clickHandler detected an event of type: " + event.type);
trace("the this keyword refers to: " + this);
}
Resultatet av spårningen kommer att se ut så här:
clickHandler detected an event of type: click
the this keyword refers to: [object global]
Man skulle kunna tro att this refererar till myListenerObj och att spårningsutdata är [object Object], med det refererar i stället till det globala objektet. När du anger namnet på en dynamisk egenskap som argument till addEventListener(), kan Flash Player eller AIR inte skapa någon bunden metod. Det beror på att det du anger som listener-parameter inte är något annat än minnesadressen för avlyssnarfunktionen, och Flash Player och AIR kan inte länka den minnesadressen till myListenerObj-instansen.