Back to Entry Page

Handler Precedence in ActionScript
Or, The Click Problem

The Problem

We need to consider another significant flaw in ActionScript: common mouse events are handled inconsistently by buttons and movie clips.

Confusingly, ActionScript uses two different pairs of events to respond to the pressing and releasing of the mouse button (what we more loosely refer to as a click). Movie clips interpret these actions through the mouseDown and mouseUp events (whose names, at least, will be familiar from JavaScript and other languages). Buttons respond to press and release.

Press and release are localized to the (virtual) button (i.e., Flash symbol) over which the cursor is positioned when the (physical) mouse button is pressed or released. That is, the release event happens only when the mouse button is released while the cursor is over a button symbol. A button press/release that happens with the cursor outside any button generates no event.

As the demonstration below shows, this provision does not apply to the mouseDown and mouseUp events used by movie clips. The mouseDown event simply means that the physical mouse button has been pressed. It says nothing about the cursor position. If you write a script on a movie clip that handles the mousedown event, it will respond no matter where the cursor is. Notably, it will also respond to a click on a button symbol, which in this case generates both a press and a mouseDown.

To see the problem in action, hold the mouse button down while over any of the symbols below. Then try mousing down while your cursor is over no symbol.

If you do not address this problem, you will not be able to use movie clips with mouse event handlers in any timeline that also includes buttons, since clicks on the buttons will activate the clip handlers as well.

The Solution

Luckily, there is a relatively straightforward solution for the click problem. For every movie clip, ActionScript has information about its total width and height (this._width, this._height) and the X-Y coordinates of its registration point (this._x, this._y). Using this information, we can build a simple script to locate the four corners of the object. Then we build a four-way compound test, using Boolean and, to determine if a given mouseclick happened while the cursor was within the rectangle described by those four points. The script looks like this:

onClipEvent(mouseDown){

//You talking to ME?
  //Assuming registration point is in middle of symbol, 
  //find left, top, right, bottom limits
  myLeft = this._x - (this._width/2);
  myRight = this._x + (this._width/2);
  myTop = this._y-(this._height/2);
  myBottom = this._y +(this._height/2);	

  //Was click within limits of this clip?
  if(_root._xmouse > myLeft && _root._ymouse > myTop
  && _root._xmouse < myRight && _root._ymouse < myBottom )
    {
      //...desired response goes here
    }
}

To test this script in action, try out the demonstration below:

Code for the second example above (i.e., with the fix in place) can be found in clickFix.fla, which is on Crow at multimediaShare/clickFix/.

Observation

Again, you have to wonder about Macromedia's software engineering standards. Obviously, the Flash player contains basic code necessary to find the limit points of an object and determine if a mouse click falls within those limits--we know this because button symbols do the trick nicely. Why then is it necessary for scripters to re-do this work in the case of movie clips? Go figure... but it's worth remembering that you won't run into this sort of problem in Lingo, Java, JavaScript, or XML.


University of Baltimore Logo

Copyright © 2002 School of Information Arts and Technologies