I'm trying to send a simple test message from javascript to flash, but I'm getting the error:
Object #<HTMLObjectElement> has no method "listenToJS"
I've read a number of questions on this on stack, but I feel like either the browser is not getting the proper reference to my flash object, or within my actionscript I am not putting my flash function in the proper place.
So within html I am embedding flash with SWFObj:
<div id="flash_content">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1280" height="800" id="tourFlash" name="pano" class="pano">
<param name="movie" value="VRDemo.swf" />
<param name="menu" value="false" />
<param name="wmode" value="transparent" />
<param name="allowscriptaccess" value="always" />
<!--[if !IE]>-->
<object type="application/x-shockwave-flash" data="VRDemo.swf" width="1280" height="800" class="pano">
<param name="menu" value="false" />
<param name="wmode" value="transparent" />
<param name="allowscriptaccess" value="always" />
<param name="allownetworking" value="all" />
<param name="flashvars" value="zoom=null&pan=null&sound=null" />
<!--<![endif]-->
<a href="http://www.adobe.com/go/getflashplayer">
<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
</a>
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
</div>
<script>
var flashObj;
$(document).ready(function(){
flashObj = document.getElementById('tourFlash');
$('#interface').click(function(){
console.log('click');
talkToFlash();
});
});
function talkToFlash(){
flashObj.listenToJS('hello from js');
}
function listenFromFlash(flashMessage){
console.log(message);
}
</script>
The click handler is triggered, but here I get the error. My flash file uses a document class, and within the document class is the public function. Flash is structured like this:
package com.company.vr {
import flash.display.*;
import flash.events.*;
import com.greensock.*;
import com.greensock.easing.*;
import flash.external.ExternalInterface;
import flash.system.Security;
Security.allowDomain("*");
public class VR_TestDocument extends MovieClip {
public function VR_TestDocument() {
ExternalInterface.addCallback("talkToFlash", listenToJS);
}
public function listenToJS(message){
trace ("from js: " + message);
var flashMessage = message + " flash";
ExternalInterface.call("listenFromFlash", flashMessage);
}
}
}
---UPDATE---
It looks like External Interface doesn't like SWFObject for some reason. If I switch to the method of embedding that Flash used in this example:
it works, but I feel like swfobject is the best way to embed flash. Anyone got any ideas?
If you embeded flash in html as your code above, note, that second tag object also has to contain attribute id, corrected code is here:
But of course, swfobject is the best way to embed flash. Correct html code looks like:
--Update--
You have to select the correct flash element on the page. (Depends on the browser). As an example, here is code to get correct flashObj:
It could very well be a timing issue -- Flash Player takes a little bit of time to initialize ExternalInterface, and then a little bit more time to load your SWF. Your example code is running on DOMReady, which is NOT a guarantee that the SWF has loaded or that ExternalInterface has initialized within Flash Player.
I recommend querying the SWF to see if it has finished loading. There's an example (using dynamic publishing) on LearnSWFObject.com: http://learnswfobject.com/advanced-topics/executing-javascript-when-the-swf-has-finished-loading/
UPDATE: After re-reading your code and some other suggested answers, I noticed you're using
document.getElementById
to grab your<object>
. When using the nested<object>
markup, this won't work (except in IE, which uses the outer<object>
).swfobject.getObjectById
was specifically created to address this issue. Try editing your JS to useswfobject.getObjectById
.