Posted by: Dennis | August 21, 2007

External Interface Tip

This article will treat solutions to “swfObject.callback() is not a function” problem when using ExternalInterface in Flash/Flex.

Ok, not so long ago I had to test some interaction between JavaScript and ActionScript. It wasn’t the first time I was using EI, and since it’s always good to start from a working examle, I set up the one provided by Adobe, test it – works fine.

(An important note – you have to run it from a web server and add it to flash player’s security domain. I’ll show you how later). Now in this example the flash function is called the onClick event of form button is fired:

<input type="button" value="Send" onclick="callAsFunction();" >

while what I needed was to call the AS function as soon as the document loads. I decided to put it in body’s onLoad event:

<body onload="callAsFunction();">

and SURPRIIIIIIIISSEEEEEEEE !!!! – not working!
I double check everything again and nothing. WHAT THE … ?! [picture of me scratching the head]. It is there, why isn’t it working?? The error message thrown by JavaScript was “blabla.blabla() is not a function”
I am a person who thinks that if smth isn’t working right in a computer program, it’s most certainly your fault, not computer’s, so I start thinking of a solution. I searched the net and all the examples/tutorials/forums out there were variations of the one provided by Adobe, which is calling AS function after the button is pushed. GREAT!
I made another test, called the function from within a <script> tag after the embed code – didn’t work either. So I thought, perhaps in both cases the flash object simply isn’t ready yet.
Another test – add a timeout:

setTimeout('callAsFunction();', 100)

TADAAA, it worked, BUT, only in 9 out of 10 page refreshes. If I set timeout to smth like 500 it solves the issue, but it’s not a good solution. Who wants to wait half a second? It can screw many things up. So what do we do? We make flash tell JavaScript when it’s loaded and ready, and only after that, call AS functions. Piece of cake!
Here is the JS code:

    function onFlashReady() {
		sendToAS("another test message");
    }

    function callJS(value) {
        onFlashReady();
        return "Hi Flash.";
    }

    function thisMovie(movieName) {
         if (navigator.appName.indexOf("Microsoft") != -1) {
             return window[movieName];
         } else {
             return document[movieName];
         }
     }
     function sendToAS(value) {
         thisMovie("test").callAS(value);
     }

and AS code:

import flash.external.*;

System.security.allowDomain("http://localhost");

tf.text = "Flash loaded and ready!";
tf.text += "nEI available: " + ExternalInterface.available;

var wasSuccessful:Boolean = ExternalInterface.addCallback("callAS", this, func);
tf.text += "nAdd callback success: " + wasSuccessful;

greeting = String(ExternalInterface.call("callJS", "Hello JS!"));
tf.text += "nI called Javascript and it said: " + greeting;

function func(value:String) {
	tf.text += "nJavascript called me, saying: " + value;
}

Note that you need a TextField on the stage with the name “tf”. Give the swf object the name “test” when embedding.
You can also download the source files here: http://www.box.net/shared/ocq972d435
IMPORTANT!!! – the html file needs to be run on a web server. Simply douleclicking it won’t work!!!
This should appear in the textfield:
“Flash loaded and ready!
EI available: true
Add callback success: true
Javascript called me, saying: another test message
I called Javascript and it said: Hi Flash.”

Have fun coding!

Advertisements

Responses

  1. hi,

    i am trying to call a flex function called myflexFunction from JS. it works well when i call it once.

    But when i need to to be called to set of movies then it is not working.

    code:
    for(var i=0; i<DC[j].childNodes.length; i++)
    {
    if (DC[j].childNodes[i].id.substr(0, 4) == “Item”)
    {
    var no=DC[j].childNodes[i].id.charAt(4);
    var myid = “myMovie”+no; document.getElementById(myid).myFlexFunction(myid);
    }

    }

    then flex function will in turn call a JS named test. this function is called only for one of the movies. But why all the movies are not calling the test function?

  2. how to i call the flash function from vc++?

  3. I am not familiar with CPP and the IDE’s.
    I am sorry, but I am not the one who can give you the answer

  4. 1137: Incorrect number of arguments. Expected no more than 2.

    I think there are one too many args here:
    var wasSuccessful:Boolean = ExternalInterface.addCallback(“callAS”, this, func);

  5. Hi,

    I call a function of vc++ activeX from “Test.html” file.I can play Flash files by clicking “play” button in html file.(The play fuction is defined in vc++ workspace.)

    Now I have fullscreen button in “test.html”.
    so my question is what will be my fuction defination for fullscreen in vc workspace.

    Thnx in advance,
    Nandan

  6. Nandan, I am sorry but I can’t help you with your issue

  7. Dude, this rules; totally just saved me from major headaches. Thanks!

  8. You saved my life! Thanks! It worked in IE8 but not in FF. I almost had the same thoughts but didn’t know how to tell JS when Flash is ready!

    It’s really a ‘peace of cake’ ;D

  9. Exactly what I’m looking for. Thank you.

  10. somehow the downloaded example doesn’t work. do you happen to know about flash-settings that can be wrong on my pc?

  11. cool…. its working…

  12. Beware of flash firebug .. it was the reason my calls weren’t working

  13. […] External Interface Tip « ActionScript 3, Flash, Flex Reflections Ok, not so long ago I had to test some interaction between JavaScript and ActionScript. It wasn’t the first time I was using EI, and since it’s always good to start from a working examle, I set up the one provided by Adobe, test it – works fine. (An important note – you have to run it from a web server and add it to flash player’s security domain. I’ll show you how later). […]


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: