问题
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:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/external/ExternalInterface.html#addCallback()
it works, but I feel like swfobject is the best way to embed flash. Anyone got any ideas?
回答1:
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:
<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" id="tourFlash1">
<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>
But of course, swfobject is the best way to embed flash. Correct html code looks like:
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>js</title>
<script type="text/javascript" src="swfobject.js"></script>
<script>
function talkToFlash(){
document.getElementById('flash_content').listenToJS('hello from js');
}
var flashvars = {};
var params = {
allowscriptaccess: "always"
}
var attributes = {};
swfobject.embedSWF("VRDemo.swf", "flash_content", "550", "400", "10.0.0", false, flashvars, params, attributes);
</script>
</head>
<body>
<div id="flash_content"></div>
</body>
</html>
--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:
flashObj1 = document.getElementById('tourFlash');
flashObj2 = document.getElementById('tourFlash1');
flashObj = flashObj1.talkToFlash != undefined ? flashObj1 : flashObj2;
回答2:
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 use swfobject.getObjectById
.
来源:https://stackoverflow.com/questions/14345936/how-to-allow-javascript-to-communicate-with-flash-object-htmlobjectelement-h