3

I am calling an Actionscript function from JavaScript and it works in all browsers except for IE9. I narrowed it down to the js function that retrieves the movie object:

<script type="text/javascript"> 
var swf;
... 

function flashReady() // This is called from ActionScript
{
    swf = getSWF("MyMovie");
    swf.MyExternalFunction(); 
}

function getSWF(movieName) 
{ 
    if (navigator.appName.indexOf("Microsoft") != -1) 
    { 
        return window[movieName]; 
    } 
    else 
    { 
        return document[movieName]; 
    } 
} 
... 
</script>

Here is my HTML:

<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="1" height="1" id="MyMovie">
    <param name="allowScriptAccess" value="always" />
    <param name="movie" value="/swf/movie.swf" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#ffcc00" />
    <embed src="/swf/movie.swf" quality="high" bgcolor="#ffcc00" width="1" height="1" name="MyMovie" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>

When I am calling the external function like this:

swf.MyExternalFunction(); 

In IE9 i get a JS error:

"Object doesn't support property or method 'MyExternalFunction'" 

Apparently window[movieName], which was good for IE, does not work in IE9 the way it used to. Any suggestions?

:::UPDATE:::

Here is my solution so far. It may not look pretty, but it works:

var movie = false;

function initSWF(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        //alert("IE");
        if (typeof (window[movieName].MyExternalFunction) == 'function') {
            // alert("< IE9");
            movie = window[movieName];
        }
        else if (typeof (document[movieName].MyExternalFunction) == 'function') {
            // alert(">= IE9");
            movie = document[movieName];
        }
    }
    else {
        // alert("NON IE");
        movie = document[movieName];
    }

    return ((movie) ? true : false);
}

Then it is used like:

function flashReady() // This is called from ActionScript
{
    if(initSwf("MyMovie")) {
        movie.MyExternalFunction();
    } else {
        alert("Failed to initialize");
    }
}
OctoRazor
  • 31
  • 1
  • 3
  • Probably not related, but you should use ` – shanethehat Jul 20 '11 at 14:07
  • Yes, thank you, I actually used type="text/javascript", but this should not matter. – OctoRazor Jul 20 '11 at 14:14
  • When are you calling your external function ? It's possible that your Flash object isn't loaded when you call it. Also we aren't in 1990, `document.getElementById` works on all browser, don't use `window[movieName]` or `document[movieName]`. – HoLyVieR Jul 20 '11 at 16:43
  • I have a flashReady() JS function that is called from the swf once it is loaded. In its turn it tries to init by getting the correct obgect from getSWF(). To my knowledge window[movieName] gets the tag and document[movieName] gets the tag. For which browser are you suggesting using the getElementById? – OctoRazor Jul 20 '11 at 16:50
  • 1
    @OctoRazor All of them, `window[movieName]` is an old feature of IE that was used to get an element by his ID. `document.getElementById` is now the standard way of accessing an element by his id. It works on every browser, unless your dealing with browser that are more than 14 years old (ex.: IE4). – HoLyVieR Jul 20 '11 at 16:59
  • @HoLyVieR The whole idea of using window[name]/document[name] is to get tag in IE and tag in non-ie (btw, by name, not by id). Adobe manual for AS3 suggests using it, so it is not 14 years old. http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7cb1zephyr_serranozephyr.html If i give same id's to both of my object and embed tags, it will just pick the first one it finds in DOM. Even if I use jQuery.. something like $("#MyMovie > object") or $("#MyMovie > embed") I get same error as with getElementById: TypeError: MyExternalFunction is not a function – OctoRazor Jul 20 '11 at 17:36

2 Answers2

0

I've had this exact same problem with IE9, for me, it was the case of IE9 caching the flash. Try clearing the browser cache (f12 for developer tools and there's an icon to clear the cache or ctrl-R i think), and then give it a shot again.

If that doesnt, try debugging by delaying your javascript call to actionscript by 1 or 2 seconds, something along the lines of this :

<SCRIPT LANGUAGE='Javascript'>

function delayForFlash() {
setTimeout("startFlash()", 1000);
}

function startFlash() {
getFlashMovie("flashdemo").restartFlash();
}

window.onload = function(){ delayForFlash();}
</SCRIPT>

This is to give enough time for your flash to load everything up.

Stefan
  • 352
  • 3
  • 15
  • Thanks for the tip, but this is not it. I know exactly when the movie is ready, as I trigger the JS init process from the movie itself. In any case, just out of curiosity I tried adding a delay, and it did not work. – OctoRazor Jul 20 '11 at 17:39
  • So the way your code works is: ActionScript calls a Javascript, then the Javascript passes on some information back to the Actionscript? I used to do this, but then i switched over to waiting for flash to load, and javascript makes first contact to the actionscript, due to some IE9 caching problems. Do you encounter this problem while running locally or are you running on a server? – Stefan Jul 20 '11 at 18:06
  • The problem is there both on the server and locally. The function can not be called even after minutes of waiting (i know, silly). You can use Dev Tools console to test this. I posted a new solution to my question. It is dirty and relies on a specific AS function to be there for JS to verify its availability. – OctoRazor Jul 20 '11 at 18:13
0

I've been having similar trouble except that it was working in IE9 and not IE7/8. I believe the cause of both our problems are the same though. I solved it by stumbling across this wonderful article on A List: Apart http://www.alistapart.com/articles/flashsatay/

Following the article, your correctly formed HTML should read:

<object type="application/x-shockwave-flash" data="/swf/movie.swf" width="1" height="1" id="MyMovie">
    <param name="allowScriptAccess" value="always" />
    <param name="movie" value="/swf/movie.swf" />
    <param name="quality" value="high" />
    <param name="bgcolor" value="#ffcc00" />
</object>

In particular notice that I've added a type and removed the <embed> tag.

As far as I can see, there is no need to use the <embed> tag any more. And removing it means we can use much simpler code to fire our ExternalInterface function:

// After the flash object has loaded...
var movie = document.getElementById('MyMovie');
if (typeof movie.MyExternalFunction === 'function') movie.MyExternalFunction();

I hope this helps.

Liam Newmarch
  • 3,935
  • 3
  • 32
  • 46