Search code examples
javascriptactionscript-3flashswfobjectexternalinterface

how to allow javascript to communicate with flash (Object #<HTMLObjectElement> has no method


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?


Solution

  • 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;