Interesting notes on External Interface JavaScript Call-Backs To Flash

This week we had a big project due for a new Movie that is coming out in a few weeks time.         The majority of the site was built-in Flash but I needed to use an External Interface call to JavaScript in order to display dynamic content in an iFrame div pop-up. The first call from Flash to JavaScript to open the window and display the dynamic link worked fine on every browser  I tested.   When the call is made, I turn on translucent white cover layer in Flash so the site appears behind it and the game pop-up appears on top, in HTML. So far, so good.

The problems started to crop up when I added functionality to the game pop-up window to close the the pop-up box and then tell Flash to remove the white translucent layer. It just would not work on every browser.   For reference, here is a brief set of code that Flash AS3 uses to tell JavaScript that is has a call-back function when making the initial ExternalInterface call:

ExternalInterface.addCallback("gameClose", gameClose);

So, basically this tells JavaScript that when the ExternalInterface call is made, the “gameClose” function should be added by the DOM to the Flash Movie Object and the gameClose (second paramter) is the name of the call-back function in AS3 that will be called.

The AS3 gameClose() function simply turns off the translucent white cover layer.

In Javascript, when the close button on the div that holds the game iframe is clicked, this code is fire off:

var callResult=thisMovie("flashObject").gameClose();

“flashObject” is both the name=”” and id=”” attribute that I put into my Object and Embed Tags. At first I was using the SwfObject to do this, but some of the browsers were coming back with dom errors saying that gameClose() was not a function. I then tried to use the straight Object tags that are exported from Flash on publish. Still, I had inconsistent ability to fire off the gameClose() call back function.  It was getting weird.

I then switched up to the old-style Object tag with an embed tag inside like this:

http://site.swf

This got the call-back to work in both Firefox and Chrome (previously it was only working in Chrome).  The problem was that IE 9 simply would tell me that gameClose() was not part of the DOM. It actually could not even recognize that “flashObject” was an object on the page.

Frustrated, I put in code to try to echo back what “flashObject” actually was:

if (document["flashObject"] == null) {
       swf= window["flashObject"];
 }else{
      swf= document["flashObject"];
 }

 console.log("swf=" + swf):

On the browsers where the close button worked fine, “swf” was logged as an HTMLEmbedObject. On the browsers where it did not work, it came back as a
NodeList.

So, of course gameClose() did not exist on the NodeList because is was a actually a collection of nodes with the name “flashObject”. There were two of those, one in the Object tag and one in the embed tag.

The answer was to loop through the node list and find the node that was actually the HTMLEmbedObject type (or just simply use the second node in the flashObject collection for iE). The second node was the embed tag that IE was looking for while the object tag would throw an error.

It worked and I was on my way to finishing the project in the “nick” of time.

2 comments

Leave a Reply