Not signed in (Sign In)

Vanilla 1.0.3 is a product of Lussumo. More Information: Documentation, Community Support.

    • CommentAuthoraduston
    • CommentTimeJan 8th 2007
     
    Dear SWFObject Forum,

    When a swf is attached to a page in IE6 by setting innerHTML on a page element, will it accept calls made to methods registered through ExternalInterface.addCallback?

    I am using the latest version of swfobject.js. I have a very simple swf (.as copied to bottom) and a very simple html page
    that uses swfobject.js and a little bit of javascript to load it. The html/js file contents are copied to the bottom of this message as well. To run my very simple page, just compile the .as into a .swf and, in the html, click addSwf, which will add the swf to the page, then click on "Click here" in the swf. On Firefox this results in the alert "called back!" but in IE6 (Flash Player 9.0.28) it does nothing. Note: you will have to put TestExternalInterface.swf and swfobject.js into swf/ and js/
    directories, respectively, to run this... or just change the relevant text in the .html file.

    I have played around a bit with this in IE and it seems that whenever a swf is attached to a page by setting innerHTML on a page element, the swf will not accept calls made to a method registered through ExternalInterface.addCallback. It is strange, because this seems to be significant behavior, yet I can only find a few places on the web (e.g. http://blog.deconcept.com/2006/08/03/swfobject-144-released/#comment-14905 ) where this behavior is noticed by anyone.

    So, I am very curious about how one can dynamically add a swf to a page which needs to receive calls from javascript. Any
    thoughts/comments?

    Thank you very much,
    Adam

    --- .as file source ---

    package {
    import flash.display.Sprite;
    import flash.display.SimpleButton;
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.external.ExternalInterface;

    [SWF(width="300", height="300")]
    public class TestExternalInterface extends Sprite
    {
    public function TestExternalInterface()
    {
    var tf : TextField = new TextField();
    tf.text = "Click here";
    var sb : SimpleButton = new SimpleButton(tf, tf, tf, tf);
    addChild(sb);
    sb.addEventListener(MouseEvent.CLICK, buttonClicked);
    }

    private function buttonClicked(event : MouseEvent) : void {
    ExternalInterface.addCallback("callMeBack", callMeBack);
    ExternalInterface.call("callToCallMeBack");
    }

    private function callMeBack() : void {
    ExternalInterface.call("alert", "called back!");
    }
    }
    }

    --- html/js source ---

    <html>
    <head>
    <script src="js/swfobject.js" type="text/javascript"></script>
    <script>
    function getSwfObject() {
    var retVal = new deconcept.SWFObject("swf/TestExternalInterface.swf",
    "testWidget", "300px", "300px", null, "#FFFFFF");
    retVal.addParam("allowScriptAccess", "always");
    return retVal;
    }

    function getSwfHtml() {
    return getSwfObject().getSWFHTML();
    }

    function addSwf() {
    var div = document.createElement("div");
    div.innerHTML = getSwfHtml();
    document.body.appendChild(div);
    }

    function callToCallMeBack() {
    document.getElementById("testWidget").callMeBack();
    }
    </script>
    </head>
    <body>
    <a href="javascript:addSwf();">addSwf</a>
    </body>
    </html>
    • CommentAuthoraduston
    • CommentTimeJan 9th 2007
     
    I should add just a bit more information here. I have had success with two other methods of attaching swfs to html dynamically without losing the ability for the swf to receive calls from javascript. They are:

    1. Use document.write . This is the method that the Adobe Flash Detection Kit uses. But with document.write I cannot control the element in which my swf ends up, or at least not so long as that element is also dynamically created and added to the page.

    2. I can use document.createElement("object") and then build the attributes and param elements through similar DOM calls, but then I have noticed that on IE the classid attribute must be added the dynamically-generated object element in a separate JS<->browser cycle, or the swf will never appear. This seems like a hack to me.

    So, it seems that to add swfs to html in IE6 dynamically, one must either resort to a very limiting method (#1) or a hack (#2). This doesn't seem right to me, as Google (for example) seems to dynamically place swfs all over the place (e.g. maps and finance). So, how does Google do it? Any advice would be sincerely appreciated.

    Thanks again,
    Adam
    • CommentAuthorGeoff
    • CommentTimeJan 9th 2007 edited
     
    I've never had problems using ExternalInterface + swfobject... here's a test page from a while back that uses it:

    http://blog.deconcept.com/code/flashregex.html

    it uses external interface to call out and get a result back from js... and it's embedded using swfobject.
    • CommentAuthorGeoff
    • CommentTimeJan 9th 2007
     
    Oh, I just looked at your code, and it's really odd... why are you bypassing the built in so.write() method? There are things that happen in that method that may need to be in place for it to work correctly... and you are bypassing all the plugin detection if you do it your way...

    it seems like you are taking stuff that is build into swfobject and rewriting it yourself, but i don't see why.
    • CommentAuthorkamermans
    • CommentTimeJan 9th 2007 edited
     
    Just a heads up and an example, ExternalInterface() will not work with or without SWFObject if you put the SWF in a FORM (at least in IE it won't). I have written a script that corrects this problem and I have a complete working example of the ExternalInterface() here: http://blog.deconcept.com/swfobject/forum/comments.php?DiscussionID=19&page=1#Item_5
    • CommentAuthoraduston
    • CommentTimeJan 9th 2007
     
    Dear Geoff and kamermans,

    Thank you very much for your replies, but I'm afraid there is still a problem here, and my initial hunch is that SWFObject will fail to work in this way for SWFs that were written in AS3 and compiled with mxmlc. I altered my js to use SWFObject#write; I copied the text below. Yet the callback still fails. As you can see, my html/js and actionscript files are very, very simple; it is the bare minimum necessary to obtain a callback using ExternalInterface.addCallback. Yet, I obtain the same behavior: The callback works in FF but not in IE6. You can easily prove this for yourself by compiling my AS3 with mxmlc and opening the html.

    I know that you'll be less likely to answer if you have to do legwork, so, as an alternative, please provide your actionscript for the two examples you gave. I would be extremely happy to compile them and see them work; that way I would know that there was a way out of this.

    Thanks again for your help,
    Adam

    my new html/js, which uses SWFObject#write:

    <html>
    <head>
    <script src="js/swfobject.js" type="text/javascript"></script>
    <script>
    function getSwfObject() {
    var retVal = new deconcept.SWFObject("swf/TestExternalInterface.swf",
    "testWidget", "300px", "300px", "9", "#FFFFFF");
    retVal.addParam("allowScriptAccess", "always");
    return retVal;
    }

    function addSwf() {
    var div = document.createElement("div");
    getSwfObject().write(div);
    document.body.appendChild(div);
    }

    function callToCallMeBack() {
    document.getElementById("testWidget").callMeBack();
    }
    </script>
    </head>
    <body>
    <a href="javascript:addSwf();">addSwf</a>
    </body>
    </html>


    as a reminder, my Actionscript:

    package {
    import flash.display.Sprite;
    import flash.display.SimpleButton;
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.external.ExternalInterface;

    [SWF(width="300", height="300")]
    public class TestExternalInterface extends Sprite
    {
    public function TestExternalInterface()
    {
    var tf : TextField = new TextField();
    tf.text = "Click here";
    var sb : SimpleButton = new SimpleButton(tf, tf, tf, tf);
    addChild(sb);
    sb.addEventListener(MouseEvent.CLICK, buttonClicked);
    }

    private function buttonClicked(event : MouseEvent) : void {
    ExternalInterface.addCallback("callMeBack", callMeBack);
    ExternalInterface.call("callToCallMeBack");
    }

    private function callMeBack() : void {
    ExternalInterface.call("alert", "called back!");
    }
    }
    }
    • CommentAuthorGeoff
    • CommentTimeJan 10th 2007 edited
     
    var div = document.createElement("div");
    getSwfObject().write(div);

    you need to append that div to you document before it will work... (and before you call so.write on it)
    • CommentAuthoraduston
    • CommentTimeJan 10th 2007
     
    Thanks, Geoff. That worked. I am amazed. I am also baffled by the behavior... if the object element is added to the div before the div is attached to the rest of the DOM hierarchy, then everything works except for ExternalInterface callbacks. If the object element is added to the div after the div is attached to the rest of the DOM hierarchy, then everything including ExternalInterface callbacks work correctly. Well I am quite baffled but very grateful. Thanks again.

    "This nature full of hints and mysteries,
    Untrackt conclusions, broken lights and shapes"
    -Tennyson
    • CommentAuthorange52
    • CommentTimeJan 15th 2007
     
    Geoff and aduston,

    I'm baffled and amazed by these results as well! I'm having a similar problem where my ExternalInterface methods are not working out, and it is only happening on IE. Can you provide a few more details on what this problem was all about, and how I might troubleshoot my own situation? I'm not even adding in the fancy document.createElement() to the mess -- it is pretty simple and straight-forward SWFOjbect.

    Any more hints on where this problem comes from would be a great help. Thanks all!
    ange52
    • CommentAuthorkamermans
    • CommentTimeJan 17th 2007
     
    ange52 - Maybe this page will help: http://devel.teratechnologies.net/swfformfix/extinterface-devel.php it's an example of bidirectional communications between JS and Flash via ExternalInterface(). Also, in case you didn't see the note above, is your SWF inside a FORM? If it is it will NOT work without using a script like SWFFormFix2
    • CommentAuthorange52
    • CommentTimeJan 22nd 2007 edited
     
    Thanks, Kamermans. I think I have identified the thing that is confusing me: getting a hold of the swf movie with JavaScript so that you can call the Flash method on that. Right now, I use SWFObject to place my swf on the page, then I'm using prototype to grab the swf later on and call the method on it. Something like:

    var myGame = $("gameSwf");
    myGame.externalMethod();

    Again, this works out just fine in all other browsers except for IE. I think that it might have something to do with this JS method I've seen in a few places (including the link you put on your last post), but I don't understand what it does...

    function thisMovie(movieName) {
    var isIE = navigator.appName.indexOf("Microsoft") != -1;
    return (isIE) ? window[movieName] : document[movieName];
    }

    Should I be using this method instead of anything from prototype? Could this be where the problem is coming from?
    • CommentAuthorkamermans
    • CommentTimeJan 22nd 2007
     
    You should be using that method instead of yours, yes. IE only works like window["myMovie"].externalMethod() - it's really quite buggy. Sometimes you can get away with document.getElementById("myMovie").externalMethod() but it's not consistent.
    • CommentAuthorGeoff
    • CommentTimeJan 23rd 2007 edited
     
    I've always just used the document.getElementById("myMovie").externalMethod() method and haven't had problems with it.

    You just have to wait until the movie is loaded and available to js before calling stuff.
    • CommentAuthorange52
    • CommentTimeJan 23rd 2007
     
    Well I have used

    document.getElementById("myMovie").externalMethod()

    with no luck. I have also tried the shorter prototype syntax of

    $("myMovie").externalMethod()

    No luck there, either. Both times these lines get called on the window's load. What is more, neither of these two issues should explain why the problem would be happening only with IE, while FF (Mac & PC) and Safari handle this without any problems.

    Could there be any other things I'm doing wrong?
    • CommentAuthorkamermans
    • CommentTimeJan 23rd 2007
     
    Geoff - I think document.getElementById("myMovie").externalMethod() fails if "myMovie" is in a form in IE.
    • CommentAuthorange52
    • CommentTimeJan 24th 2007
     
    No forms here!

    ...Could I be doing something more fundamentally wrong? Why might IE, and only IE, be so picky?
    • CommentAuthorGeoff
    • CommentTimeJan 26th 2007
     
    well i'm not sure - it must be something with your strange js setup, as we use external interface all the time in projects here and it works just fine in IE.

    maybe try cutting out your extra scripts and see if you can get it working on just a simple page with only your swf on it?
    • CommentAuthorTheOrange
    • CommentTimeJan 29th 2007 edited
     
    Hi, I'm having a problem with an application I making, it works this way, I created a swf that communicates with my server and it send the info to a javascript function to write html in the page.

    I'm doing it this way because the swf and js are located in my server, but they are referenced on my client's html to load content from my server into their page, I didn't use AJAX due to the crossdomain problem.
    The problem is that when calling javascript functions from flash it works perfectly, however when calling flash functions from javascript it cannot find the functions, in other words the ExternalInterface.addCallback does not work.
    Flash --> Javascript (OK)
    Javascript --> Flash (DOES NOT WORK)
    However if I do the same thing with a page in my own server it works perfectly... THIS HAS TO BE A BUG in the ExternalInterface..
    Can anyone help me..?
    • CommentAuthorGeoff
    • CommentTimeJan 30th 2007
     
    you may need to use allowscriptaccess=always - as there are some security restrictions placed on the flash player to prevent cross site scripting vulnerabilities. it's not a bug.