8bitrocket.com
4Feb/129

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:

<object id="flashObject" name="flashObject"
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
width="800" height="600" align="middle">
 <param name="movie" value="site.swf" />
 <param name="wmode" value="transparent" />
 <param name="allowscriptsccess" value="always" />
 <param name="allowsetworking" value="true" />
 <param name="menu" value="false"/>
<embed src="site.swf" width="800" height="600"
id="flashObject" name="flashObject"
type="application/x-shockwave-flash"
allowscriptsccess="always" allowsetworking="true"
wmode="transparent" menu="false"></embed></object>

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.

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.
  • http://twitter.com/thegoldenmule Benjamin Jordan

    Did you try using SWFObject? It will give you the flash object so you don’t have to find it.

  • http://twitter.com/thegoldenmule Benjamin Jordan

    Whoops! I see you were trying SWFObject at first. Weird, I’ve never had that problem.

  • http://www.8bitrocket.com 8bitjeff

    Ben, it is strange, but I think the problem stemmed from IE 9 changing itself to “quirks” mode based on the content of the iFrame. (it was linking directly to a swf not an html file). very very odd.

  • Anonymous

    I think that was it.  Linking directly to the .swf even messed up SWfObject.

  • http://www.webhostings.in/ Hosting companies

    Well I am quite sure that it would not be new for you but your blog s fantastic!

  • http://www.websitedesignpositive.co.uk/ Mike

    Well written article.I appreciate your writing skills.Its great.You have done a great job by sharing this post with us.I like this post.Keep sharing with us in future too.

  • http://www.paidsearch.co.uk/ liz

    Hey,nice post. You have have explained each & every thing so nicely.You are really a good teacher.Thanks for sharing this coding with us.Its really important to us.

  • http://halsotips.info/ halsotips

    wow. this is very good tutorial. you write the problem and its solution. thanks for sharing.

  • http://precisionsignz.com/ campaign sign

    Excellent article, I will recommend my friends to read it.