Table of Contents

MovieClip.onData ( ) Event Handler Flash 5; callback form introduced in Flash 6

handler executed when the clip receives variables, or a portion of a loaded movie
mc.onData()

onClipEvent (data) {
  statements
}

Description

The onData( ) event handler is the callback form (and more modern analogue) of the legacy onClipEvent (data) event handler. The onData( ) handler executes when external data is loaded into a movie clip. It can be triggered by two quite different circumstances, according to the kind of data being loaded—either external variables, or a .swf or .jpg file. Note that as a variable loader, the onData( ) event is made obsolete in Flash 6 by the LoadVars class's download monitoring methods. As a movie loader, the onData( ) event is (in my experience) too buggy to use in Flash 5, though it appears to be working properly in Flash 6.0.29.0.

When we request a series of variables from a server using loadVariables( ), we must wait for them to load completely before using their information. When a movie clip receives the end of a batch of loaded variables, the onData( ) event is triggered, telling us it's safe to execute code that relies on the variables.

For example, suppose we have a guest book movie in which visitors enter comments that we store on a server. When a user attempts to view a comment, we request it from the server using loadVariables( ). But before we can display the comment, we must pause at a loading screen until we know that the requested data is available. An onData( ) event handler tells us when our variables have loaded, at which point we can safely display the comment to the user.

The following code shows a simplified excerpt of a guest book that loads variables when the user clicks a button. In the example, the button loads two URL-encoded variables from a text file into a movie clip using loadVariables( ). The movie clip defines an onData( ) event handler that executes when the variables have loaded. From inside that handler, we display the values of the variables. We know the variables are safe to display, because the code in the handler isn't executed until it's triggered by the onData( ) event (i.e., after the data is received):

// CONTENT OF OUR guestbook.txt FILE
name=judith&message=hello
   
// BUTTON INSIDE OUR CLIP
guestBook_mc.go_btn.onRelease = function {
  this._parent.loadVariables("guestbook.txt");
};
   
// HANDLER ON OUR CLIP
guestBook_mc.onData = function {
  trace(name);
  trace(message);
};

The second use of the onData( ) event relates to the loading of external .swf and .jpg files into movie clips with the loadMovie( ) function. When a .swf file is loaded into a host clip, the file begins playing immediately by default, even if it is only partially loaded. This is not always desirable—sometimes we want to guarantee that all or a certain percentage of a .swf has loaded before playback begins. We can make that guarantee with an onData( ) event handler and some preloading code.

The onData( ) event occurs each time a host movie clip receives a portion of an external .swf file. The definition of what constitutes a "portion" is more complex than you might expect. In order for an onData( ) event to be triggered, at least one complete new frame of the external .swf file must have loaded since either the last onData( ) event fired or the .swf file started loading. (More than one frame of the .swf file may actually have loaded in that amount of time, but one frame is the minimum number required to prompt an onData( ) event.)

The execution of onData( ) event handlers is tied to the rendering of frames in the Player. With every frame rendered, the interpreter checks to see if part of an external .swf file has been loaded into a clip that has an onData( ) event handler. If part of an external .swf file has been loaded into such a clip, and the loaded portion contains at least one new frame, then the onData( ) event handler is executed. This process happens once—and only once—per tick of the frame rate (even while the playhead is stopped).

Note that because the onData( ) event happens on a per-frame basis, movies with higher frame rates tend to have smoother-looking preloaders because they receive more frequent updates on the status of loading .swf (or .jpg) files.

The exact number of onData( ) events triggered during a loadMovie( ) operation depends on the distribution of content in the .swf file being loaded and the speed of the connection. A single-frame .swf file, no matter how large, will trigger only one onData( ) event. On the other hand, a .swf file with 100 frames may trigger up to 100 separate onData( ) events, depending on the movie's frame rate, the byte size of each frame, and the speed of the network connection. If the frames are large and the connection is slow, more onData( ) events will be triggered (up to a maximum of one per frame). If the frames are small and the connection is fast, fewer onData( ) events will be triggered (the entire 100 frames may be transferred between the rendering of two frames in the Player, prompting only one onData( ) event).

So how do we use an onData( ) event handler to build a preloader? First and foremost, we must be sure to use the Flash 5-style onClipEvent( ) format of the handler:

onClipEvent (data) {
  // preload code
}

Using onClipEvent(data) instead of onData( ) ensures that the handler is not deleted when we load our .swf file, because the former is attached to a clip at authoring time rather than created as a variable that will be lost when the clip loads its new content. Then, whenever an onData( ) event occurs due to a loadMovie( ) function call, we know that an external .swf file download is in progress. Therefore, from inside an onClipEvent(data) event handler, we can check whether enough of the file has downloaded before allowing it to play. We do so using the getBytesLoaded( ) and getBytesTotal( ) methods, as shown in the following example. (The _framesloaded and _totalframes movie clip properties can also be used.)

onClipEvent (data) {
    trace("data received");           // The show's about to start!
   
    // Turn on data-transfer light (indicator)
    _root.transferIndicator.gotoAndStop("on");
   
    // If we're done loading, turn off data-transfer light, and let the movie play
    if (getBytesTotal() > 0 && getBytesLoaded() =  = getBytesTotal()) {
      _root.transferIndicator.gotoAndStop("off");
      play();
    }
   
    // Display some loading details in text field variables on the _root
    _root.bytesLoaded = getBytesLoaded();
    _root.bytesTotal = getBytesTotal();
    _
root.clipURL = _url.substring(_url.lastIndexOf("/") + 1, _url.length);
}

This example also provides feedback while the movie is loading. Note that the .swf file being loaded should have a stop( ) function call on its first frame to prevent it from automatically playing before it is completely downloaded. A variation of this example is available at the online Code Depot.

Bugs

In Flash 5 on a high-speed connection, the onData( ) event does not always execute when a .swf file completely loads. This unofficial bug has not been verified by Macromedia, but it appears to be fixed in the release 29 of Flash Player 6 (6.0.29.0).

See Also

loadMovie( ), loadVariables( ), the LoadVars class, MovieClip.getBytesLoaded( ), MovieClip.getBytesTotal( ), MovieClip._framesloaded, MovieClip._framestotal, MovieClip.onLoad( ); Chapter 10


Table of Contents