My simple ActionScript I am trying to use Flash's ExternalInterface to setup a callback so that JavaScript can call a method on my Flash object. Everything works fine in Safari, Firefox and in IE, but I cannot get Chrome working. When I try the code on Chrome, I get the following error:
Uncaught TypeError: Object #<an HTMLObjectElement> has no method 'setText'
Here is the example HTML I am using (again, works fine in Safari, FF and IE)
<html><body>
<div id="mycontent"></div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<script type="text/javascript">
swfobject.embedSWF("http://invincible.dynalias.com:8080/HelloWorld.swf", "mycontent", "400", "420", "9.0.0","expressInstall.swf", {}, {allowScriptAccess:'always'},{id:'hw',name:'hw'});
function getFlash(movieName) {
return ( navigator.appName.indexOf("Microsoft") != -1) ? window[movieName] : document.getElementById(movieName);
}
</script><p>
<input type="text" id="exampleText" /> <input type="button" value="Set Text" onclick="getFlash('hw').setText(document.getElementById('exampleText')
.value)" />
</body>
</html>
and here is the ActionScript...
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.external.ExternalInterface;
import flash.system.Security;
public class HelloWorld extends Sprite {
private var textField:TextField = new TextField();
public function HelloWorld() {
Security.allowDomain("*");
ExternalInterface.addCallback("setText", this.setText);
textField.text = "Hello, world!";
addChild(textField);
}
public function setText(text:String):void {
this.textField.text = text;
}
}
}
I got the same problem, to fire and recieve listener events between javascript and flash.
The solution was to use AC_OETags.js file from Adobe as embedd script instead of JQuery flash. (It is found in the zip file under Client Side detection, Adobe probably have it some other places as well)
The trouble based on a race condition when the flash builds the javascript callbacks in the browser. This is not handeled correctly by a straight embed for some reason.
Then you can do: (works in IE, FF, Safari, Crome,++)
After struggling a lot, I finally decided to use the official solution from Adobe:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html
Search for
ExternalInterfaceExample.as
.There is a workaround to the problem by disabling Chrome built-in flash plugin:
This is not a solution, but shows why this happens on Chrome. Chrome accompany with a built-in flash plugins, that often cause the troubles when we use the ExternalInterface of AS3, it's annoying.
I agree with Robson that it is a race condition, but it's not in 'writing the Flash tag' and adding a timer is not a good solution - in fact its very dangerous.
The problem is that the SWF itself isn't loaded and had a chance to initialize your external interface. For a small SWF in Chrome the timing may be more sensitive than other browers, but the underlying problem isn't specific to Chrome.
What you need to do is this :
In Actionscript
Call this function from your constructor :
In your HTML
You may find on your local machine that it works without this, but as soon as you add network delays into the equation you'll regret not doing this. An arbitrary timer is a bad idea because you will still get the error on a slow connection. This method lets the page call the flash object at the earliest possible time.
Note: Using jQuery's 'on ready' pattern is NOT a solution to the problem - although at first I mistook it for one.
Also swfobject's
callbackFn
is also not a solution becasue that just tells you when the tag is inserted and not when the SWF is loaded.I was having problems with ExternalInterface and Firefox and Chrome and discovered that the Adobe Script was not writing the Flash tag quickly enough, so when the browser tried to find the addCallback() function it was not there at the time.
Simply putting my Javascript function that calls the Flash created addCallback() in a window.setTimeout() calling solves the problem. Delays less than 200 ms still make the problem to occur.
I didn’t have to use the solution of trying to find if the “length” attribute exists in the document[FlashId] object. Just calling “FlashEmbed = document[FlashId]” worked just fine.