Using Event Handlers to Trigger Action

     

The Flash Player generates an event to signal that something potentially significant has happened in your program. An event is like an announcement. Some object has to be listening for the event and respond to it for it to have any effect. Many built-in objects automatically listen for certain types of events. However, they never respond automatically. You enable a response by giving the responding object an event handler or callback function for a particular event.

If an object doesn't listen for a particular type of event by default, it may be possible to register the object to be a listener for that type of event. You register the object with the designated broadcaster for that type of event. For the example, you can register to receive all Mouse events or all Key (keyboard) events.

Many events don't accept registrations. Either an object is a potential responder or it's not. Even if an object is a potential responder , it still needs an appropriate callback function to actually respond.

General-Purpose Event Engines

The event model discussed in this chapter allows you to listen for a limited set of events, such as key presses, mouse clicks, text field changes, and Stage resizing. However, situations may arise in which you want to listen for other events, typically associated with objects or components that you have created. A general-purpose event engine allows you to do this. For instance, the new V2 components include such an event engine, UIEventDispatcher. Another is AsBroadcaster, added in the previous version of Flash MX; it's discussed in AsBroadcaster.htm on the CD.


Let's take two examples: the user releasing the mouse button and a movie clip named myClip entering a new frame.

Objects in your movie do not automatically respond when these events occur. However, if you add an onClipEvent(enterFrame) or an onEnterFrame() event handler to myClip , the statements in the event handler are executed each time myClip enters a new frame. myClip receives or traps the event, using an event handler or callback function specific to the enterFrame event.

For instance, you can define an onEnterFrame event handler for myClip by putting this line of code in a frame on the timeline containing myClip :

 myClip.onEnterFrame = function () {trace("just testing");}; 

The Flash Player calls your callback function every time the movie enters a new frame. In this case, it displays "just testing" in the Output window once per frame.

There is no way for any object other than a movie clip to receive this event. There is no way to register to listen for the enterFrame event.

Similarly, you can add an onMouseUp event handler to a movie clip. In that case, the event handler is called when the mouse button is released:

 myClip.onMouseUp = function () {trace("mouse button released");}; 

In addition, any other object can create an onMouseUp callback function and then register as a listener with the Mouse object (the broadcaster) to receive this event. Registration is accomplished using the addListener() method of the Mouse object. The following three lines form a working program that creates an object named myObj , creates an onMouseUp callback function for myObj , and registers myObj to receive the onMouseUp event:

 myObj = new Object(); myObj.onMouseUp = function() {trace("myObj received the event");}; Mouse.addListener(myObj); 

From that point on, myObj.onMouseUp fires whenever the mouse button is released.

The names of callback functions are predetermined: They always begin with on , as in onEnterFrame . The circumstances under which they are called are also predetermined. However, it is totally up to you to decide what statements to put in the callback function. For instance, your callback function might display a new graphic when a button is pressed, rearrange items on the Stage when the Stage is resized, check the value of a variable after a movie clip containing the variable has loaded, or check the contents of a changed text field and take action based on the text.

All callback functions belong to responding objects: they are methods of those objects. If the object is a movie clip, button, or text field, the callback function executes only if the object is currently on the Stage.

In some cases, it's easy to describe the relationship between an event and an object or class. For example, the Stage object broadcasts the onResize event. No one listens for this event by default, but other objects can register, using the addListener() method of the Stage object, to receive the onResize event.

Other classes that have no default "audience" but offer registration for their events include ContextMenu and MovieClipLoader, both new in Flash MX 2004.

graphics/new_icon.jpg

The onSelect event of the ContextMenu class is called when a user brings up a custom context menu (Windows: right-click, Mac: Ctrl-click) that you have created, before the menu actually displays. There is one onSelect event for your entire custom menu, and one onSelect event for each custom item on the menu.


For more on the ContextMenu class, see Appendix A "ActionScript Reference," page 910 , and contextMenu.fla on the CD accompanying this book.


graphics/new_icon.jpg

The MovieClipLoader class has five events ( onLoadComplete , onLoadError , onLoadInit , onLoadProgress , onLoadStart) used to give you more control when loading SWFs and JPGs.


For more on MovieClipLoader, see "Loading and Unloading External Content," in this chapter, page 520 .


As Table 20.5 shows, relationships between classes and events may be a little more complicated. Each row represents an event handler. Each column represents an object class. In the table, an E (for "Event") indicates that the event is received by objects in that class by default; all you have to do is create the event handler (no registration required). An L (for "Listener") indicates that the object accepts registrations for that event.

A blank entry indicates that the object does not receive that event by default. In that case, you can scan the row to see whether any object accepts registrations for the event.

Note that the table does not include the static on and onClipEvent event handlers.

Table 20.5. Relationships Between Dynamic Event Handlers and Objects
 

Button

Key

LoadVars

MovieClip

Mouse

Selection

TextField

Sound

XML

XML Socket

onChanged

           

E,L

     

onScroller

E

   

E

   

E,L

     

onSetFocus

E

   

E

 

L

E

     

onKillFocus

E

   

E

   

E

     

onRollOver

E

   

E

           

onRollOut

E

   

E

           

onPress

E

   

E

           

onRelease

E

   

E

           

onReleaseOutside

E

   

E

           

onDragOut

E

   

E

           

onDragOver

E

   

E

           

onMouseUp

   

E

L

         

onMouseDown

   

E

L

         

onMouseMove

   

E

L

         

onMouseWheel

   

E

L(**)

         

onKeyUp

L

 

E

           

onKeyDown

L

 

E

           

onUnload

   

E

           

onEnterFrame

   

E

           

onLoad

 

E

E

     

E

E

 

onData

   

E

       

E

E

onConnect

             

E

E

onClose

             

E

E

onSoundComplete

           

E

   

onID3

           

E

   

Legend:

(**)Windows only. (New in Flash MX 2004.)

E = object receives this event by default

L = object accepts registrations for this event


Static and Dynamic Event Handlers

Event handlers can be object actions or frame actions.

"Selecting Frame Actions or Object Actions," page 445 , in Chapter 19, explains the difference between object actions and frame actions. Chapter 19 also shows how to create movie clip event handlers, using object actions.


There are just two basic event handlers that are object actions: on (for buttons ) and onClipEvent (for movie clips). For each of these, the parameter after the event handler name determines which event they trap. For instance, on(press) traps a button press, and onClipEvent(enterFrame) traps the enterFrame event. To attach an event handler to an object, click on the button or movie clip on the Stage; then use the Actions pane to create the event handler. You cannot attach these two event handlers programmatically while the movie is running, nor can you change or delete them at runtime. They are static or immutable.

In contrast, event handlers in frames are attached programmatically while the movie is running. For instance, to use the XML onLoad event handler, you first create an XML object programmatically and then attach the event handler, also programmatically, like this:

 myXML = new XML(); // create XML object myXML.onLoad = function(success) {trace("loaded !")}; // attach handler 

For more information on XML, see "XML Data," page 634 , in Chapter 22, "External Communications."


Event handlers that are created programmatically can also be changed or deleted programmatically at runtime. They are dynamic .

Whereas static events are associated only with buttons and movie clips, you can create an event handler dynamically for a wide variety of object classes, including all those shown in Table 20.5. Every static on and onClipEvent event has a dynamic equivalent. For instance, onEnterFrame is the dynamic equivalent of onClipEvent(enterFrame) .

System Events and User Input Events

The two basic kinds of events in Flash are system events and user input events. System events are generated by the movie. They include a movie clip entering a frame, for example, or an external data load operation completing.

User input events, on the other hand, begin with a mouse click or a keypress . Or, more precisely, they arrive through the mouse or keyboard interfaces, which can also accommodate other input methods such as voice. User input events include all events associated with the Button , Key , Mouse , Stage , and TextField classes. Many movie clip events are also user input events because they duplicate the functionality of Button , Key , Mouse , and TextField events.

Registering Listeners

Every dynamic event handler function is a property of an object. The object may belong to a built-in class, such as those shown in Table 20.5. In that case, the object probably receives one or more events by default. You just create the callback function for the particular object instance, and you're finished.

If you want an object that belongs to a built-in class to receive events it doesn't receive by default, or if you want a custom object that you have created to receive events, another step is involved: You must register the object as a listener.

You register an object as a listener by using the addListener method of the class with which you're registering. For example, a movie clip normally receives onKeyUp and onKeyDown events only when it has keyboard focus. To make it receive these events under all circumstances, you create callback functions and register the movie clip as a listener with the Key class, like this:

 myClip.onKeyUp = function () {trace("onKeyUp fired");}; myClip.onKeyDown = function () {trace("onKeyDown fired");}; Key.addListener(myClip); 

Dynamic event handlers have a number of advantages over static ones:

  • The dynamic approach is more flexible because you can decide programmatically at runtime which listeners to register and which events to create event handlers for. With the static approach, you need to decide which objects get which event handlers when you're authoring the movie.

  • The dynamic approach allows you to put your code wherever you want. It doesn't force you to attach it to the movie clip. You might be able to centralize all your code on the main timeline, for instance, making it easier to find and edit.

  • Dynamic event handlers are real functions, whereas static event handlers are not. That means that you can call dynamic event handlers explicitly, pass them parameters, and define local variables within them. None of those things are possible with static event handlers.

  • There are just 9 static movie clip events, implemented as parameters to onClipEvent . There are 18 dynamic movie clip events.

  • For both movie clips and buttons, there are no static equivalents for onSetFocus and onKillFocus . Thus, you can't programmatically control the way the static event handlers relate to keyboard focus.

  • The dynamic onPress and onRelease event handlers can make a movie clip act like a button, firing its events only when it has focus, and displaying a hand icon. Achieving the same effect with the static mouseUp and mouseDown events takes more work.

NOTE

You can turn an ordinary movie clip into a "button movie clip," because movie clips can take all the same events and have all the same behaviors as buttons, with the fortunate exception of scope. A button movie clip is a movie clip that acts like a button but offers more flexibility and retains its own scope rather than scoping to the timeline it's on.


The process for creating a button movie clip is described in "Movie Clip Events," later in this chapter, page 513 .


Finally, using a movie clip just to trap events is like using a Swiss Army knife just for the corkscrew. A custom object uses less memory than an empty movie clip because it doesn't contain movie clip properties that are irrelevant to trapping events.

The only compelling reason to use static clip events is to use onClipEvent(load) for movie clips that are manually placed on the Stage at authoring time. The dynamic onLoad event does not work in this case.

For more details on onLoad and onClipEvent(load), see "Movie Clip Events," later in this chapter, page 513 .


Scoping and the this Keyword with Event Handlers

Inside the static event handlers, on and onClipEvent , both the this keyword and direct references (with no path specified) refer to the Timeline of the clip to which the event handler is attached. For instance, the following are equivalent:

 onClipEvent(enterFrame) {      _x++; } onClipEvent(enterFrame) {      this._x++; } 

With dynamic event handlers, however, the situation is more complex. Every dynamic event handler is a method of an object, and inside the event handler, this refers to the object. Direct references, on the other hand, scope to the Timeline on which the event handler function is defined. Thus, if the following code is placed on the Main Timeline, this.myVar refers to myClip.myVar , whereas myVar refers to _root.myVar , as you can verify by clicking the mouse:

 _root.createEmptyMovieClip("myClip",1); myVar = "main timeline"; myClip.myVar = "myClip"; myClip.onMouseUp = function() {      trace(this.myVar); // "myClip"      trace(myVar); // "main timeline" } 

As with other methods, you can define local variables in dynamic event handlers. For example, you could add the following as the first line of the myClip.onMouseUp function in the preceding example:

 var myVar:String = "local"; 

The trace(myVar) statement in the last line then displays "local" rather than "main timeline" .

You can point another object's event handler at myClip.onMouseUp , and the value of the this variable inside myClip.onMouseUp changes to the other object. The direct reference to myVar , on the other hand, still scopes to the Timeline on which the function literal is defined.

NOTE

When the scope of a variable or other data item is the scope in which it is defined, the item is said to be lexically scoped ”scoped where it's written.


For instance, suppose you create another clip named myClip2 , give it its own myVar property, and give it an onMouseDown property referencing the myClip.onMouseUp event handler defined in the previous example. Here's the code:

 myClip2.myVar = "myClip2"; myClip2.onMouseDown = _root.myClip.onMouseUp; 

Although myClip.onMouseUp and myClip2.onMouseDown refer to the same function literal, myClip2.onMouseDown fires when the user depresses the mouse button, and this means myClip2 inside the function. It displays "myClip2" and "main timeline" . On the other hand, myClip.onMouseUp fires when the user releases the mouse button, and this means myClip , so it displays "myClip" and "main timeline" . In both cases, direct references still refer to the Main Timeline. To summarize: The value of the this variable is the object associated with the calling method, whereas the direct reference to myVar scopes lexically.

Calling Event Handlers Explicitly

Even though event handlers have the special property of being called automatically by the Flash Player under predetermined circumstances, invoking event handlers explicitly is also legal. You might want to invoke them, for instance, if you have created an event handler in one object and want to execute it on another object. Using the Function.apply() or Function.call() method allows you to specify the meaning of this within the call.

For examples of explicit invocations of event handlers, see invokeHandlersExplicit.htm on the CD accompanying this book.


Event Handlers and Focus

Text fields, buttons, and button movie clips all support the onSetFocus and onKillFocus events, which fire when the object gets or loses keyboard focus.

By default, onKeyUp and onKeyDown event handlers associated with these objects do not fire unless the object has keyboard focus ”that is, unless the keyboard cursor is on the object. (The static equivalents, onClipEvent(keyUp) and onClipEvent(keyDown) , fire regardless of keyboard focus.)

Alternatively, you can use an addListener statement to register an object to receive a particular class of events. In that case, the object's dynamic event handlers for that class will always fire, whether or not the object has focus.

Thus, say you have a movie clip, myClip , and you want it to trap onKeyUp and onKeyDown events. First, create the callback functions:

 myClip.onKeyUp = function () {trace("onKeyUp");}; myClip.onKeyDown = function () {trace("onKeyDown");}; 

Then you have two options. One possibility is to make myClip into a button movie clip. The callback functions are enabled when myClip has keyboard focus.

The other possibility is to make myClip a listener of the Key class, like this:

 Key.addListener(myClip); 

The callback functions are continuously enabled.

Disabling and Deleting Event Handlers

Deleting an event handler is easy because it's just an ordinary variable. Here's an example:

 delete myClip.onKeyDown; 

If you've registered a listener for a class from which you're no longer going to trap any events, you should remove the listener, as well, like this:

 Key.removeListener(myClip); 

If you want to temporarily disable an event handler so that it doesnt use up processor cycles when it isn't performing any useful function, see disableHandler.htm on the CD accompanying this book.


Button Events

Flash has eight static button events: press , release , releaseOutside , rollOver , rollOut , dragOut , dragOver , and keyPress .

It has nine dynamic button events: onPress , onRelease , onReleaseOutside , onRollOver , onRollOut , onDragOut , onDragOver , onKillFocus , and onSetFocus .

Notice that buttons do not receive dynamic Key events by default. However, you can make a button a listener of the Key class so that it can receive onKeyUp and onKeyDown events, the dynamic equivalents of keyPress .

All button events fire only in response to the primary mouse button. There is no reaction to a secondary mouse button.

All mouse- related button events (which include all button events except keyPress ) fire just once, at a transition point. For instance, even though the user holds down the mouse button, the press event occurs just once, when the button is first pressed.

Except for the first paragraph on focus events, each of the following paragraphs covers just a single event, which may be trapped by either a static or a dynamic event handler. Thus, referring to "the press and onPress events," for example, is a bit like saying "the radio and TV news." There is just one event, but you're finding out about it through two different channels. You can also say "the press events," meaning "the press event, whether captured statically or dynamically."

onKillFocus , onSetFocus

The onSetFocus event occurs when a button gets keyboard focus. Keyboard focus changes when the user presses the Tab or Shift+Tab keys to navigate among text fields and buttons on a page. The onKillFocus event occurs when the button loses keyboard focus. Focus events were implemented primarily for input text fields. They provide a convenient hook for any necessary pre- and post-processing as the user fills in the fields. These events can also be useful for buttons and button movie clips. For instance, if you're using a Submit button, when the button gains focus, you could check to make sure the user has filled in all the fields properly. When the button loses focus, you could generate a Thank You message.

press / onPress

The press and onPress events occur when the user presses the primary mouse button while the mouse pointer is within the hit area of the button. This event provides the fastest possible reaction because it fires when the mouse button is pushed down, as opposed to when it is released. On the other hand, this does not allow the user to change his or her mind after pushing the mouse button. This event is most appropriate for games (where reaction time is critical), and it also works for checkboxes, where the user can undo the choice just by clicking the checkbox again.

release / onRelease

The release and onRelease events occur when the primary mouse button is both pressed and released while the mouse pointer is within the hit area of the button. These events allow the user to change his or her mind by moving the pointer outside the hit area before releasing the mouse button.

releaseOutside / onReleaseOutside

The releaseOutside and onReleaseOutside events occur when the user presses the mouse button while the pointer is within the hit area, and then moves the pointer outside the hit area and releases the button. If the user needs to drag something from one place to another, for instance, you could put actions within these event handlers to determine whether the mouse pointer is in the correct place when the user releases it.

rollOver / onRollOver

The rollOver and onRollOver events fire when the mouse pointer moves into the hit area while the mouse button is up (not depressed). Although the Over state of the button and the corresponding _over frame of a button movie clip handle the visual aspects of rollover, the event handler allows you to do something programmatically at this point, as well. For instance, if you want to do something just before the user presses a button, you can use these events.

rollOut / onRollOut

The rollOut and onRollOut events fire when the mouse pointer moves out of the hit area while the mouse button is up ( not depressed). Up and _up handle the visual aspects of rollout, but the event handler allows you to do something programmatically. This event can be used, for instance, to do something after the user finishes interacting with a particular button.

dragOut / onDragOut

The dragOut and onDragOut events fire when the mouse pointer moves out of the hit area while the mouse button is pressed.

dragOver / onDragOver

The dragOver and onDragOver events fire when the user performs a dragOut -type action, does not release outside, and then moves the pointer back inside the hit area and releases.

keyPress

The keyPress event occurs when the user presses a key on the keyboard. The format is as follows :

 on (keyPress  key  ) {  statement1  ;  statement2  ; } 

key is a string in quotation marks representing the key pressed. For alphanumeric keys, key represents the key literally, like this:

 on (keyPress "a") {      trace("a pressed"); } 

Alternatively, key can be one of 14 special keywords representing nonalphanumeric keys, such as arrow keys, the spacebar, and the Enter key:

<Backspace>

<Delete>

<Down>

<End>

<Enter>

<Home>

<Insert>

<Left>

<PgDn>

<PgUp>

<Right>

<Space>

<Tab>

<Up>

 

You use the keywords like this:

 on (keyPress "<Space>") {      trace("space bar pressed"); } 

Unlike mouse-related button events, keyPress typically occurs repeatedly if the user holds down the key, though this could vary with the keyboard and the operating system configuration.

The keyPress event handler must be attached to a button instance. In addition, the Flash Player must have mouse focus for key-related event handlers to fire. Movies get mouse focus automatically in the Flash Player or in a projector, but not in the browser. Therefore, for browser compatibility, you might want to make users click a button before beginning keyboard input.

TIP

In the Flash authoring environment, you may need to click in an input text field to give the movie keyboard focus.


TIP

Because keyboard focus behaves differently in the authoring environment, Flash Player, and browser, you should test any movie that involves keyboard focus in all the environments where it may be used.


In almost every way, the keyPress event is more limited and less flexible than the onKeyUp and onKeyDown events associated with the Key object. For instance, keyPress doesn't support function keys, Caps Lock, or the Cmd (Mac) or Ctrl (Windows) keys. Nor does it support listeners. Probably most importantly, keyPress requires that you check for a specific key; it does not allow you to get an event when any key is pressed and then determine which one it was. The Key object overcomes all these limitations.

The keyPress event does have one unique capability that the Key object events don't: It can disable the Tab key for focus shifting. To prevent users from using the Tab key to shift focus in the standalone player, projector, and browser, you attach the following to a button:

 on(keyPress "<Tab>") {      // must have some statement here      dummy = null; } 

Then, if you want, you can use Key object events to detect the Tab key and Selection.setFocus to explicitly change focus.

The Key object events, on the other hand, allow you to capture the Tab key without disabling it for focus shifting.

Key Events

onClipEvent(keyDown) fires when the user presses any key on the keyboard, and onClipEvent(keyUp) fires when the user releases any key.

Four methods associated with the Key object allow you to determine which key was pressed:

  • Key.getCode() returns the keycode of the last key pressed.

  • Key.getAscii() returns the ASCII code of the last key pressed.

  • Key.isDown(keycode) returns true if the specified key is being pressed now.

  • Key.isToggled(keycode) returns true if the specified key (Caps Lock or Num Lock) is toggled on now.

You can use the Key.isDown() method by itself in an enterFrame event handler, to check for a key on every frame. For instance, this code checks for the Tab key on every frame:

 myClip.onEnterFrame = function () {      if (Key.isDown(Key.TAB)           trace("Tab key pressed"); } 

This code could be appropriate in a game, for example, where catching keypresses as fast as possible is a primary design goal.

Notice the use of the TAB constant in caps.

Unless you're checking on every frame, using Key.isDown() alone is an unreliable method of detecting keypresses because the user could press the key in a frame where you're not checking for it. To get around this problem, use a Key event handler to detect the keypress and one of the Key methods to find out which key it was. The following example uses the onKeyDown event handler with the Key.getAscii() method ”and the String.fromCharCode() method ”to translate the ASCII code into an alphanumeric character:

 myClip.onKeyDown = function () {      trace( String.fromCharCode(Key.getAscii()) ); }; 

When the Flash Player has focus, on(keyPress) will always fire when the appropriate key is pressed. Events associated with the Key object, however, may or may not fire, depending on two factors: keyboard focus and listener registration.

You can get Key -related event handlers to fire in two ways:

  • Any object's Key -related event handlers will fire, regardless of keyboard focus, if the object is registered as a listener with the Key object

  • If a button or button movie clip has keyboard focus, its Key -related event handlers will fire. It does not have to be registered as a listener with the Key object.

Table 20.6 summarizes these two rules.

Table 20.6. When Key -Related Event Handlers Fire
 

Object Registered as Key Listener

Object Not Registered as Key Listener

Object has keyboard focus

Any object's Key events will fire.

Button and button movie clip's Key events will fire.

Object doesn't have keyboard focus

Any object's Key .events will fire.

Key events will not fire.


Mouse Events

There are static and dynamic versions of mouseDown , mouseUp , and mouseMove . For example, for mouseDown , the dynamic version is onMouseDown, and the static version is onClipEvent(mouseDown) . They fire when the user presses the primary mouse button, when the user releases the button, and whenever the mouse moves, respectively. mouseMove may also fire when a movie loads.

Although Mouse events can now be associated with buttons, they fire no matter where the mouse pointer is on the Stage, ignoring both keyboard focus and button hit areas. In addition, unlike Button events, Mouse events do not change the mouse pointer to a hand cursor.

One use of mouseMove or onMouseMove is to "wake up" a program after an idle period. If you're using mouseMove or onMouseMove in a limited context like this, consider setting them equal to null while they're not being used. Otherwise, they can generate large numbers of events in a short time, taking up a lot of processor cycles.

One common use of Mouse events ”in conjunction with the two Mouse methods, show() and hide() , which make the mouse pointer visible or invisible ”is to create a custom mouse pointer. You hide the standard pointer, use _root._xmouse and _root._ymouse to check for mouse position whenever a Mouse event occurs, and then consistently display the custom mouse pointer at that position.

Movie Clip Events

Movie clips receive all the Button , Key , and Mouse events. In addition, movie clips receive enter frame , load , unload , and data events. The dynamic forms of these events ” onEnterFrame , onLoad , onUnload , and onData ”can be associated with the Main Timeline. The static forms can be attached to movie clips, but not to the Main Timeline. Movie clip events sometimes make things more straightforward. For instance, they eliminate the need to put code on a movie clip just because you want to execute some action on every frame.

enterFrame

The enterFrame event has already appeared many times in this book. It occurs each time the playhead enters a frame, and it is the most commonly used event in Flash.

data and onData

The data and onData events fire when external data loads into a movie as a result of a loadVariables() or loadMovie() function.

The XML class also has an onData event, which is covered in "XML Data," page 634 , in Chapter 22.


The loadVariables() function fires a single data event when an entire batch of variables finishes loading. In contrast, loadMovie() fires a series of data events up to a maximum of one per frame, as the movie loads. Thus, with loadVariables() , the data event tells you that you have all the data and can start to work with it. With loadMovie() , a data event tells you that some portion of the loaded movie has arrived, but you may need to check whether enough of it has arrived for your purposes. To check, you can use the getBytesLoaded() and getBytesTotal() functions, the _framesloaded and _totalframes movie clip properties, or ”for Flash 4 compatibility ”the deprecated ifFrameLoaded() function.

Sample movie ondata.fla on the CD provides a simple example of using the onData event with loadVariables() .

The data event is covered in "The LoadVariables() Global Function," page 626 , in Chapter 22.


load and onLoad

The load or onLoad event fires when a movie clip is initially loaded into your movie.

The LoadVars object also has an onLoad event. See Chapter 22, page 625 .


The Sound object has an onLoad event, too, covered in "Sound Events," later in this chapter, page 515 .


The clip may have been manually created with the authoring tool, created when another clip was duplicated with duplicateMovieClip() , loaded from the Library with attachMovie() , or loaded as an external SWF with loadMovie() .

In most cases, dynamic and static event handlers provide almost identical functionality. Dynamic event handlers provide advantages such as greater flexibility, easier code centralization, and local scoping. Still, anything that can be done with dynamic event handlers can usually also be done with static event handlers, and vice versa. Not so with the load and onLoad events. In fact, when you first start trying to apply the onLoad event, it appears nearly useless. Why?

The problem is that the onLoad event handler must be created before the clip loads. However, if the clip hasn't loaded, there is nothing to assign the onLoad event handler to. Thus, if a clip named myClip is manually created on the Stage, and you place the following code on the first frame of the Main Timeline, the clip will already have loaded by the time the interpreter gets to your code:

 myClip.onLoad = function () {trace("myClip loads");}; // will never fire 

On the other hand, if you're going to load the clip programmatically, using attachMovieClip() , should you declare the onLoad event handler before or after the attach? If before, the clip does not exist yet, so you can't define an event handler for it. If after, the clip has already loaded, and it's too late.

One way to get a dynamic onLoad event to fire successfully is to inherit it from the class. When a new object is created, there is a time when the object is still unnamed and "unborn" but already endowed with all the shared methods and properties from the class. When the object is "born," if one of those shared methods is an onLoad event handler, it will fire.

The ActionScript 1 approach to inheriting the onLoad method from the class is shown in AS1onLoad.fla and AS1onLoad2.fla on the CD accompanying this book.


For the ActionScript 2 approach to inheriting the methods from the class, see "ActionScript 2.0: Real Class," page 540 , in Chapter 21.


unload and onUnload

The unload and onUnload events occur when you use unloadMovie() or unloadMovieNum() to unload a clip that has been loaded.

The unload event is a good place to free up resources, such as listeners, that have been associated with a movie clip. For instance:

 onClipEvent(load) {     Mouse.addListener(this); } onClipEvent(unload) {     Mouse.removeListener(this); } 

graphics/troubleshooting_icon.jpg

Can't get a dynamic movie clip event to work? See the "Troubleshooting" section at the end of this chapter, page 535 .


Creating a Button Movie Clip

Movie clips receive button events by default. This provides the foundation for creating a button movie clip. There are three other pieces of functionality that you want in a button:

  • A hand cursor , so that the user gets a visual indication when the button is clickable. By default, if you assign a button event handler to a movie clip, the clip immediately starts displaying the hand cursor when the mouse pointer is over it.

  • A hit area , defining the area of the Stage in which the button is clickable. Movie clips have a hitArea property that allows you to designate any movie clip as the hit area of the button movie clip.

  • Up, over, and down states , so that the button changes appearance when the cursor enters the hit area and when the user presses the button. You can give _up , _over , and _down labels to frames in the button movie clip's timeline, and they will automatically provide the desired behaviors. Alternatively, you can use onRollOver , onRollOut , and onRelease or onPress event handlers to implement these behaviors.

On the CD accompanying this book, sample movie dynamicButtonMovie.fla (by Helen Triolo) and sample buttonMovie.fla demonstrate two approaches to accomplishing these tasks .


Selection Events

The primary purpose of the Selection object is to help you manage keyboard focus.

Any object can receive notification of all focus changes if you register the object with the Selection object, using addListener , and define an onSetFocus event handler.

The Selection.onSetFocus event handler has the following format:

 onSetFocus (  oldFocus, newFocus  ) {  statements  } 

The following sample code creates an object and makes it listen for all onSetFocus events:

 myObj = new Object(); myObj.onSetFocus = function() {trace("focus set event occurred");}; Selection.addListener(myObj); 

This is different from the onSetFocus event handlers available by default (no addListener required) for instances of the Button , MovieClip , and TextField classes. A default onSetFocus event handler fires only when the instance it belongs to gets focus. Therefore, a default onSetFocus event handler needs only one argument, which is the old focus. The new focus is always the instance to which the handler belongs. So the format for a default onSetFocus event handler is as follows:

 onSetFocus (  oldFocus  ) {  statements  } 

If an instance of Button , MovieClip , or TextField uses addListener to register with the Selection object, the instance's onSetFocus event handler receives both kinds of notifications. This "double-barreled" onSetFocus event handler fires twice when the instance gets focus, but only once when any other object gets focus.

Sample movie selection.fla on the CD illustrates these points.

Sound Events

The Sound object has three events: onLoad , onSoundComplete and onID3 . The onLoad event fires when the sound loads, and onSoundComplete fires when the sound completes playing.

graphics/new_icon.jpg

The onID3 handler fires each time new ID3 data is available for an MP3 audio file loaded using Sound.attachSound() or Sound.loadSound() . If both ID3 1.0 and ID3 2.0 tags are present in a file, the onID3 handler fires twice.


As shown in sample movie sound.fla on the CD, you simply create the Sound object, define the event handlers, and load the sound.

TIP

Defining the event handlers before loading the sound is essential.


The Stage onResize Event

The Stage object has just one event: onResize , occurring when the user resizes the Stage. The Stage.resize event is typically used to adjust the dimensions, layout, or contents of the movie to fit the new size of the Stage.

The user can resize the Stage by clicking on boxes in the upper left (Mac) or upper right (Windows) of the Flash Player or the browser. The user can maximize the Stage or restore down or up. All these actions trigger an onResize event. Another way to resize is to drag the edges of the Player or browser window. This triggers multiple onResize events as the window continuously changes size. In the Flash Player or authoring environment, selecting View, Magnification, 100% also triggers an onResize event, but minimizing or zooming in or out does not. In addition, one or more Stage.resize events may fire when a movie is initially loaded, whether in a browser or in the Flash Player or authoring environment.

The scaleMode property of the Stage object determines how graphics are scaled and cropped as the Stage resizes. In the browser, parameters in the HTML file also affect scaling and cropping.

Although there are many combinations of scaleMode and HTML settings, here's a setup that will generally trigger the onResize event reliably:

  1. Choose File, Publish Settings. On the HTML tab, select Percent in the Dimensions combo box, leaving Width and Height at the default values of 100%. Also on the HTML tab, select Default (Show All) in the Scale combo box.

  2. Set Stage.scaleMode to "noScale" and Stage.align to "TL" . You set these programmatically, as shown in stageResize.fla on the CD accompanying this book.

Textfield Events

The four TextField events in Flash are as follows:

  • onSetFocus occurs when the keyboard focus is not on the text field and the user gives focus to it by clicking on it or entering it using the Tab or Shift+Tab keys. It has one argument: the previous focus.

  • onKillFocus occurs when the keyboard focus is on the text field and the user takes focus away from it by clicking outside it or leaving it using the Tab or Shift+Tab keys. It has one argument: the new focus.

    For more information on onKillFocus and onSetFocus , see "Selection Events," earlier in this chapter, page 515 .


    graphics/troubleshooting_icon.jpg

    Pressing Tab to change focus, but nothing is happening? See the "Troubleshooting" section at the end of this chapter, page 535 .


  • onChanged fires each time text in the field changes. Thus, it occurs every time the user types a letter in the text field and every time the user deletes a letter. Cutting a block of text or pasting in a block of text triggers just one onChanged event. This event has one argument: the text field instance name.

  • onScroller fires when the text scrolls , whether the user clicks the mouse on a scrollbar, uses the up and down arrow keys, or enters text into the text field. This event has one argument: the text field instance name.

Sample movie textfieldEvents.fla demonstrates each of these events. It contains an input text field, myText , with onChanged and onScroller events that increment variables ( myChanged and myScroller ) that are displayed in dynamic text fields.



Using Macromedia Studio MX 2004
Special Edition Using Macromedia Studio MX 2004
ISBN: 0789730421
EAN: 2147483647
Year: N/A
Pages: 339

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net