Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ActionScript 2.0 2006

.pdf
Скачиваний:
104
Добавлен:
17.08.2013
Размер:
12.47 Mб
Скачать

Chapter 24

Setting Up the Integration Kit

Setting up the integration kit is very easy. Before setting up the kit, you’ll need to download it, and you’ll need a web server space to test it on. The kit comes with a JavaScript file called JavaScriptFlashGateway.js, which you find in the installation folder within the kit. This file needs to be uploaded directly into the root folder of your web server; it will later be included into the HTML page that contains your SWF file. The next step is a bit more complex. Two ActionScript files must be placed in the default IDE classpath:

JavaScriptProxy.as

JavaScriptSerializer.as

These files are in the source folder within the kit — in the ActionScript subfolder. When you open the ActionScript subfolder you will notice the files are within a hierarchy of folders. These folders should remain as they are. Copy the com folder and all of its content. Place the copy folder in the same directory as the JavaScriptFlashGateway.fla file.

You will now be able to compile these classes into this FLA file. You should open the

JavaScriptFlashGateway.fla file and compile it now. Upload the JavaScriptFlashGateway.swf file to the same folder as the JS file you uploaded earlier. The integration kit is now installed on your server! Easy!

Calling JavaScript Functions from ActionScript

Whenever you use the integration kit, you must include the JS files from the kit. Do this using a simple include element:

<script type=”text/javascript” src=”path/JavaScriptFlashGateway.js”></script>

Replace the path with a path your HTML page can resolve to include the JS file. This file contains all the necessary methods that will be required when the Flash file makes a call to the kit.

The next step is to work within your main application. You’ll need to import the JavaScriptProxy class file. You can do this by importing it directly:

import com.macromedia.javascript.JavaScriptProxy;

The com path will need to be in the default classpath, in the same work folder as your main application FLA file, or within a custom classpath specified for your main application FLA file.

You can now construct an instance of the proxy class. In your main application FLA, you can place the following code:

var JSConnect:JavaScriptProxy = new JavaScriptProxy();

JSConnect.call(“JSMethodName”, anObject, “anExmapleString”, {x:1,y:1});

Here you can see how the new constructor allows you to access the call method of the JavaScriptProxy class. In this example the first parameter is the name of the JavaScript function you want to call. All trailing arguments are parameters to be sent to the JavaScript method. As you can see, you can send complex and simple objects. The methods in the ActionScript and JavaScript within the kit automatically handle this complexity.

608

Putting JavaScript to Work

All you need to do now is define the methods that the ActionScript can call. The arguments that must be passed to those methods will be handled by the kit automatically.

Calling ActionScript Functions from JavaScript

This operation is a bit more involved than the reverse operation covered previously. Again, whenever you use the integration kit, you must include the JS files from the kit in the HTML file, which is displaying your main application. Do this using a simple include element:

<script type=”text/javascript” src=”path/JavaScriptFlashGateway.js”></script>

Replace the path with a path your HTML page can resolve to include the JS file.

Next, in a new Script element, you need to create an instance of the FlashProxy JavaScript class. You’ll need to give the proxy a name. To be sure the proxy is unique and won’t collide with any other localConnection objects, the documentation suggests using the data and time object to create a unique String:

<script type=”text/javascript”> var uid = new Date().getTime();

var flashProxy = new FlashProxy(uid, ‘ path/JavaScriptFlashGateway.swf’); </script>

Calling this constructor actually downloads and displays the JavaScriptFlashGateway.swf file in a hidden div. This SWF, which is provided by the framework and is not something that you create yourself, will act as a shim that the JavaScript can rewrite over and over to populate with FlashVars. This data is in turn sent to your main application by the shim.

The UID must somehow find its way into the main application. Fortunately, the kit has provided you with a tool that will automatically display the main application SWF while adding the appropriate UID FlashVar. To add your main application to the web page, you can call a simple JavaScript as is demonstrated in the following code. You should change ‘path/yourMainApplication.swf’ to refer to the SWF file that is to be at the other end of your JavaScript-ActionScript connection:

<script type=”text/javascript”>

var tag = new FlashTag(‘path/yourMainApplication.swf’, 300, 300); tag.setFlashvars(‘lcId=’+uid);

tag.write(document);

</script>

You can specify more FlashVars if you want, or if your application requires them, but for the kit to work you will need the lcid variable, which must match the uid variable.

You can also set different attributes about the Object and Embed tag, which this operation creates. These include FlashTag.setBgcolor and FlashTag.setVersion, which you can use to set those attributes of the Object and Embed tag.

In this example, the FlashTag constructor is as follows:

function FlashTag(src, width, height)

{

this.src

= src;

609

Chapter 24

this.width

= width;

this.height

= height;

this.version

= ‘7,0,14,0’;

this.id

= null;

this.bgcolor

= ‘ffffff’;

this.flashVars = null;

}

If you are comfortable with JavaScript, you can, of course, modify these default values or make them additional parameters of the FlashTag method. For example, you could require the minimum version to be 8,0,0,0 rather than 7,0,14,0 as the default value so that if you do not use the setter, you can expect your application to work as desired.

The next addition is to add the actual ActionScript method call from your JavaScript. This is a simple method on the flashProxy object you instantiated with the FlashProxy constructor. An example would be as follows:

flashProxy.call(‘anActionScriptFunction’, ‘aTestString’, false, null, ‘undefined’);

The next step is to instantiate the JavaScriptProxy object in your ActionScript. Within the main application SWF file, define the connector:

var JSConnet:JavaScriptProxy = new JavaScriptProxy(_root.lcId, this);

You were required to pass two parameters to accept incoming method requests. The first is your FlashVar lcid, and you know you can find this on root. The second parameter is the object or timeline that contains the methods to which the JavaScript will have access.

All you need to do now is define the methods that the JavaScript can call. The arguments that must be passed to those methods will be handled by the kit automatically.

Try It Out

Create Communication between Browser and Movie

In this example, you have ActionScript call JavaScript with some simple parameters. Then JavaScript, upon completion of its method, will call ActionScript in response.

1.Open your favorite text editor, create a new document, and enter the following HTML and JavaScript. You will need to change the directory path of each file to match your folder layout:

<html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”> <head>

<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1” /> <title>Flash-JS Integration Kit Test</title>

<script type=”text/javascript” src=”path/JavaScriptFlashGateway.js”></script>

<!-- Set up the proxy SWF //--> <script LANGUAGE=”JavaScript”> <!--

var uid = new Date().getTime();

var flashProxy = new FlashProxy(uid, ‘ path/JavaScriptFlashGateway.swf’); //-->

</script>

<!-- Set up a method to call //-->

610

Putting JavaScript to Work

<script LANGUAGE=”JavaScript”> <!--

testJSMethod = function(testString){ alert(testString); flashProxy.call(‘testASMethod’, “true”);

}

//--> </script> </head> <body>

<!-- Insert Main Flash Applicaiton //--> <script type=”text/javascript”>

<!--

var tag = new FlashTag(‘MainApplication.swf’, 550, 400); tag.setFlashvars(‘lcId=’+uid);

tag.write(document); //-->

</script>

</body>

</html>

2.Save the file as FlashJSKit.html.

3.Open a new Flash Document. Save the Flash document as MainApplication.fla in your work folder.

4.Click the first frame in the timeline, open the Actions panel, and enter the following ActionScript code:

import com.macromedia.javascript.JavaScriptProxy; testASMethod = function (r)

{

createTextField(“responseValue”, 0, 10, 10, 200, 20);

responseValue.text = r;

};

var JSConnect:JavaScriptProxy = new JavaScriptProxy(_root.lcId, this); JSConnect.call(“testJSMethod”, “This is a test”);

5.Publish the MainApplication.fla and upload the SWF with the FlashJSKit.html from step 1 into the root directory of your web server.

6.Navigate to the FlashJSKit.html file on your server using your favorite browser.

7.Verify the alert by clicking OK. This sends a message back to your MainApplication SWF, which will display the word true.

How It Works

In this example you saw how you can easily set up JavaScript-to-Flash communication using the kit. By making sure the JavaScript and ActionScript files were present, all you needed to do was follow the documentation and then define two functions. The first is the JavaScript testJSMethod function. The second is the testASMethod function in the ActionScript. Working in concert, the two methods were able to interact seamlessly, allowing your Flash and JavaScript to communicate information.

611

Chapter 24

You can see that this method is very similar to the previous communications examples with fscommand and getURL. However, the kit packages up the best of getURL, while making a convenient and reliable method for allowing JavaScript to call ActionScript, which will work on more browsers than the document.flashMovie.SetVariables method you explored earlier.

The Flash JavaScript Integration Kit is not foolproof, however. You still must be concerned with the length of your variables, which you send to JavaScript. As well, browsers are always changing, as are the security restrictions imposed by the Flash Player. Always test your ActionScript-to-JavaScript communication on all of the browsers and systems you intend to target.

Using the External API

One aspect of Macromedia Flash that has always been an issue is the capability to interact between the Flash movie and the surrounding browser. Although the Flash JavaScript Integration Kit definitely makes this easier, it has to work around some issues with the underlying implementation of previous versions of the Flash plug-in.

With the introduction of Flash 8, a mechanism has been added directly to the Flash plug-in that is specifically designed for communication between a Flash movie and the browser. This mechanism is called the External API, and it provides a number of important benefits:

Any JavaScript function can be called from the HTML page, taking any number of arguments, and returning any value back into the Flash movie.

Different data types can be passed as function arguments, not just strings.

Individual functions within the Flash movie can be called directly from JavaScript, using standard function call syntax.

Considerable amounts of data can be passed before data length limits are reached. This was previously an issue with the getURL JavaScript technique.

This is a huge step to making Flash work more seamlessly within a larger web application, and it will be appreciated by anyone who has had to work with Flash-to-browser communication with previous versions of the plug-in. The class you work with is ExternalInterface.

ExternalInterface Class Methods

The ExternalInterface class has only two methods — addCallback() and call() — which are discussed in the following sections.

addCallback()

The addCallback() method registers an ActionScript function as being callable from JavaScript (Flash Player version 8). It indicates the functions you want to make available for external JavaScript code to call. Not every ActionScript function is exposed to JavaScript because that would be a major security risk.

612

Putting JavaScript to Work

The method takes three parameters:

functionName — A String that designates the name by which the function is accessible from JavaScript.

instance — An Object that specifies the object that holds the actual method being called, in the case of custom classes. If a function is being called from the timeline instead of from a custom class, then just put null for the value here.

functionHandle — A handle to the function or the class method to be called when the JavaScript function is invoked.

The method returns a Boolean. Here’s the syntax:

flash.external.ExternalInterface.addCallback(functionName:String, ;

instance:Object, functionHandle:Function) : Boolean

Following is an example use of addCallback():

import flash.external.*;

var methodName:String = “helloWorld”; var instance:Object = null;

var method:Function = myHelloWorld; var resultsField:TextField;

ExternalInterface.addCallback(methodName, instance, method);

resultsField = this.createTextField(“resultsField”, this.getNextHighestDepth(), ; 10, 10, 100, 20);

function myHelloWorld(inputString:String) : String

{

resultsField.text = inputString; return “received: “ + inputString;

}

The corresponding script in the HTML page would be as follows:

<script>

function callExternalInterface()

{

var flashHolder = document.getElementById(“externalInterface”);

document.forms[0].returnText.value = ; flashHolder.helloWorld(document.forms[0].inputText.value);

}

</script>

If you try this out on local files instead of files coming from a web server, you will have to change a security setting to allow the SWF file access to your local HTML file. See “Changing Security Settings” at the start of this chapter for details on how to do this.

613

Chapter 24

call()

The call() method calls a JavaScript function from within the Flash movie (Flash Player version 8). It calls a JavaScript function made available from the HTML page.

The method takes one parameter and any number of additional arguments. The parameter is a String holding the name of the JavaScript function to call. Any number of optional arguments can be added, each of which is passed to the called JavaScript function. call() returns an Object. Here’s its syntax:

flash.external.ExternalInterface.call(functionName:String, [argument1:Object], ;

[argument2:Object], ...) : Object

The following is an example of using call():

import flash.external.ExternalInterface;

var resultsField:TextField;

resultsField = this.createTextField(“resultsField”, this.getNextHighestDepth(), ; 10, 10, 100, 20);

this.createEmptyMovieClip(“getInputTextButton”, this.getNextHighestDepth()); getInputTextButton._x = 10;

getInputTextButton._y = 40;

getInputTextButton.createTextField(“buttonLabel”, ; getInputTextButton.getNextHighestDepth(), 0, 0, 100, 20); getInputTextButton.buttonLabel.textColor = 0x0000CC; getInputTextButton.buttonLabel.text = “Get Input Value”;

getInputTextButton.onRelease = function()

{

resultsField.text = String(ExternalInterface.call(“getInputValue”));

}

The corresponding script in the HTML page would be as follows:

<script>

function callExternalInterface()

{

var flashHolder = document.getElementById(“externalInterface”); document.forms[0].returnText.value = ;

flashHolder.helloWorld(document.forms[0].inputText.value);

}

function getInputValue()

{

return document.forms[0].inputText.value;

}

</script>

<form>

<input type=”text” name=”inputText” value=”” /> </form>

If you try this out on local files instead of files coming from a web server, you will have to change a security setting to allow the .swf access to your local HTML file. See the next section for details on how to do this.

614

Putting JavaScript to Work

The ExternalInterface class has only one property: available. It is a Boolean that indicates whether the external interface is enabled (Flash Player version 8).

Calling ActionScript Functions and Methods

First, look at how to initiate an ActionScript function from JavaScript. The Flash player does not allow for unimpeded access to your ActionScript code from outside the player. That would be a security risk and could have unforeseen consequences if someone figured out how to maliciously use it. The Flash player does allow for any ActionScript function or method to be called by JavaScript; however, each ActionScript function or method must be designated as being visible outside the plug-in. To expose the function, all that is needed is the ExternalInterface addCallback() method. The following section explains how this is done.

Calling an ActionScript Function from JavaScript

First, some ActionScript is needed:

import flash.external.ExternalInterface;

ExternalInterface.addCallback(“helloWorld”, null, myHelloWorld);

function myHelloWorld() : String

{

return “Hello World”;

}

The first line is an import statement that enables you to call the ExternalInterface class without having to type out flash.external.ExternalInterface every time you want to make use of the class. The second line makes the function myHelloWorld() accessible outside the plug-in; the name of the function that will be called is helloWorld(). You look at the null value shortly.

You do not need to use the new operator to create an instance of the ExternalInterface class. The methods and properties made available in the class are static, meaning that they can be called directly from the class. Because there is only ever one bridge between the Flash content and the containing HTML, the class was designed so that it is easier to invoke.

After the preceding code is placed in a blank Flash movie and is compiled, the following HTML embeds the .swf within the web page and then calls the ActionScript function when a link is clicked:

<html>

<head>

<title>externalInterface</title>

<script>

function callExternalInterface()

{

var flashHolder = document[“externalInterface”];

document.forms[0].returnText.value = flashHolder.helloWorld();

}

</script>

</head>

<body bgcolor=”#ffffff”>

<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000” ; codebase=”http://fpdownload.macromedia.com/pub/shockwave/cabs/;

615

Chapter 24

flash/swflash.cab#version=8,0,0,0” width=”550” height=”400” ; id=”externalInterface” align=”middle”>

<param name=”allowScriptAccess” value=”always” />

<param name=”movie” value=”externalInterface.swf” /> <param name=”quality” value=”high” />

<param name=”bgcolor” value=”#ffffff” />

<embed src=”externalInterface.swf” quality=”high” bgcolor=”#ffffff” ; width=”550” height=”400” name=”externalInterface” align=”middle” ; allowScriptAccess=”always” type=”application/x-shockwave-flash”;

pluginspage=”http://www.macromedia.com/go/getflashplayer” /> </object>

<form>

<a href=”javascript:;” onclick=”callExternalInterface()” /> Call helloWorld

</a><br />

Returns: <input type=”text” name=”returnText” value=”” /> </form>

</body>

</html>

Within the JavaScript, the function callExternalInterface()gets access to the Flash movie through the getElementById() method, where the id set in the <object> tag is used to find the embedded Flash content. When this is obtained, the ActionScript function is called, and its return value is assigned to a text field.

Within the Object tag, an ID needs to be set, and within both the <object> and <embed> tags, the allowScriptAccess parameter needs to be set to sameDomain. This attribute is set by default for all of the Flash authoring environment’s publishing templates; however, if you create your own, you need to make sure this parameter is present.

Finally, the call to the Flash movie is made when a link is clicked. You could have tried calling this automatically as soon as the page loaded; however, this would have had no effect. There is a delay between when the page finishes loading and when the Flash movie is loaded and ready. Until that point, any attempts at calling ActionScript functions are ignored.

Calling an ActionScript Method from JavaScript

For the most part, you will likely use the previous format to call custom functions; however, it is also possible to call class methods in much the same way. The only difference in implementation is with the addCallback() method.

The following code allows a built-in method to be called instead of a custom function. First, take a look at the ActionScript code:

import flash.external.ExternalInterface;

var mySound:Sound = new Sound(); mySound.loadSound(“http://www.nathanderksen.com/book/demoSong.mp3”); mySound.onLoad = function()

{

this.start();

}

ExternalInterface.addCallback(“setMusicLevel”, mySound, mySound.setVolume);

616

Putting JavaScript to Work

This time, when the JavaScript code makes a call to setMusicLevel(), it in fact calls setVolume() on the mySound instance.

Next, take a look at the HTML code:

<html>

<head>

<title>externalInterface</title>

<script>

function callExternalInterface()

{

var flashHolder = document[“externalInterface”]; flashHolder.setMusicLevel(Number(document.forms[0].volumeField.value));

}

</script>

</head>

<body bgcolor=”#ffffff”>

<object classid=”clsid:d27cdb6e-ae6d-11cf-96b8-444553540000” ; codebase=”http://fpdownload.macromedia.com/pub/shockwave/cabs/; flash/swflash.cab#version=8,0,0,0” width=”550” height=”400” ; id=”externalInterface” align=”middle”>

<param name=”allowScriptAccess” value=”always” /> <param name=”movie” value=”externalInterface.swf” /> <param name=”quality” value=”high” />

<param name=”bgcolor” value=”#ffffff” />

<embed src=”externalInterface.swf” quality=”high” bgcolor=”#ffffff” ; width=”550” height=”400” name=”externalInterface” align=”middle” ; allowScriptAccess=”always” type=”application/x-shockwave-flash”; pluginspage=”http://www.macromedia.com/go/getflashplayer” />

</object>

<form>

<input type=”text” name=”volumeField” value=”” />

<a href=”javascript:;” onclick=”callExternalInterface()” /> Set volume

</a><br /> </form> </body> </html>

setMusicLevel() is called and passed a number pulled from an input field. Note how the text value from the field is converted to a Number before being passed to the ActionScript method. The

ExternalInterface class allows for non-string parameters and return values, so proper typing can be used. Unfortunately, because there is no JavaScript support for strong typing, you will still need to watch for issues with data type conflicts.

Calling JavaScript Functions from ActionScript

Now take a look at how to call a JavaScript function from within the Flash movie. Unlike calling ActionScript functions from JavaScript, there are no restrictions as to which functions can be called. If the JavaScript function can be called from the HTML on the page holding the Flash movie, it can also be called from the Flash movie using ActionScript.

617