Frage

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&amp;pan=null&amp;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?

War es hilfreich?

Lösung

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&amp;pan=null&amp;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;      

Andere Tipps

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top