Not signed in (Sign In)

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

    • CommentAuthorkrazo
    • CommentTimeMay 25th 2007 edited
     
    Hey all,

    I'm having trouble with IE losing my ExternalInterface callbacks on a flex app when the swf is hidden. Has anyone else had this problem? I'm using SWFObject to embed the swf. i don't think SWFObject is responsible for the error, but i thought someone here might know about this.

    Here's some more detail on exactly what's happening. I have a complex Flex 2 application which uses SWFObject for embedding SWFs and uses External Interface for communication between the flex app and the DHTML it's embedded in.

    My SWF is embedded so that it appears as a window: resizable and movable on the page. Most of this is done in DHTML. There is an HTML link which closes the "window" by hiding the swf, the div it's in, and other elements. There is also a button in the swf which uses ExternalInterface to hide everything.

    Everything works fine in Firefox. In IE, when I click on the html link, everything operates fine. however, when i click on the close button in the swf app ( which executes the same javascript as the HTML link,) the hidden swf loses all the callbacks I've defined on it through ExternalInterface.

    So, when the "window" is reopened and the JS tries to initialize the flex app, I get a JS error saying the initialization functions are undefined.

    Here's some sample code that reflects what I'm trying to do.

    function init() {
    var asFlex = document.getElementById("asFlex");
    asFlex.style.visibility = 'visible';
    asFlex.focus();
    if(asFlex.initSelector != undefined) {
    asFlex.initSelector(a, b, c);
    } else {
    alert("initSelector is undefined");
    }
    }

    //This is being called from the flex via Externalinterface when the button in the flex app is clicked. the html link also calls this method.
    function hideAS() {
    document.getElementById("asFlex").style.visibility='hidden';
    }

    So, basically when init() is called, everything works fine and the flex app appears. Then hideAS() is called from the flex app and it is hidden. Then the next time init() is called, I'll get the alert because it has lost the callback for "initSelector()" Again this only happens in IE.

    My flex app adds the callbacks on the initialization of the application.

    I can't figure out a way around this because the browser doesn't indicate to the swf anything to tell it when it is actually visible or hidden (that I can find.) So I can't simply readd the callbacks every time it becomes visible.

    I'm not using the flash javascript integration kit because we only support flash 9 (for flex 2.0) and firefox 1.5+ and IE 6.0+ So ExternalInterface should be guaranteed to work in all the browsers and flash players we support. Is this something that kit might be able to handle/make better? or does anyone who's worked with that have any idea how or why this is happening or if there is a workaround I could use?
    • CommentAuthorAran
    • CommentTimeMay 27th 2007
     
    krazo

    I don't have any expirience of this issue, but it sounds like it could be really hard to debug :(

    One solution I can think of is to use a combination of iframe and location connection. The idea would be to embed a small external interface "controller" swf via a small iframe on the page which will listen to events from HTML via external interface and forward them on to your flex app via local connection. Reverse wise localconnection from app > controller > HTML.

    I am pretty sure that local connection is unaffected by visibility of the div etc.

    Check 1st that it is not a swfObject issue by mocking up your page with the standard <object> / <embed> method. If it is still broken , then try the above.

    Let me know how you go...

    Aran
    • CommentAuthorphilip
    • CommentTimeMay 27th 2007
     
    from what i've read on other people's blogs (sorry, no link to give), this is a Flash issue, not a SWFObject issue.

    it may be be related directly to using the 'display' attribute. possible workarounds i've heard of are to not use 'display' attribute in CSS, but to either minimize the div using the 'width' attribute (width: 0) or reposition it off-screen somewhere. i haven't tried any of this myself, so i don't know what works and what doesn't.
    • CommentAuthorphilip
    • CommentTimeMay 27th 2007 edited
     
    out of curiosity, i created a quickie "hide" script that sets the DIV's style attributes to width/height: 0 and text-indent: -9000px.

    it works great in Firefox 2, but (no surprise) in IE6 it doesn't work as well:
    http://pipwerks.com/lab/swfobject/hide-swf/

    didn't try it with ExternalInterface.

    - philip
    • CommentAuthorkrazo
    • CommentTimeMay 29th 2007
     
    Thanks for the replies.

    Aran - Using LocalConnection and a controller SWF is an interesting idea. I'd prefer not to go with that solution only because our particular architecture is going to make doing that fairly complex, but it seems like something that might work well. If all else fails, I may have to go with that. i appreciate the idea.

    Philip - I think that's exactly correct. I'd thought about doing what you suggest and was hoping there was a bit of a cleaner way of doing it. But your sample works for me in Firefox and IE7. I may be able to tweak it a little to make it work in IE6. That's probably what i'll start with.
    • CommentAuthorwarnickr
    • CommentTimeMar 2nd 2008
     
    I think I figured out a work-around for this. Create a regular button on the HTML page that contains the Flash SWF that you are hiding. Then, when hiding the SWF from inside the SWF, make an ExternalInterface call to a javascipt function that sets focus to that button and then clicks it. It worked for me.
    • CommentAuthorAran
    • CommentTimeMar 2nd 2008
     
    @warnickr - Isn't the issue after the swf is hidden and you are trying to make it visible again? Basically the issue in my understanding is that if a swf is hidden it cannot take ExternalInterface calls and loses and previous registrations...

    Perhaps an iframe which actually kills/reloads the app?

    Aran
    • CommentAuthorwarnickr
    • CommentTimeMar 3rd 2008
     
    Actually, for me the problem occurs at the point where the SWF is hidden using an ExternalInterface call that hides a div or iframe that contains the SWF. I played around with it quite a bit and I scripted the HTML button click without setting focus and it didn't work. I even tried using timers, thinking it might be a timing thing. Then the thought occurred to me that it might be a focus thing. So, I tried scripting setting focus to the button and then clicking it, and it worked. After I show the iframe again, I can still call my ExternalInterface callbacks from javascript.
    • CommentAuthorwarnickr
    • CommentTimeMar 3rd 2008
     
    I'm not sure if I answered you directly Aran, but just to make sure, I thought that I would add that the original issue at the top of this thread is the same issue that I was having. The problem IS NOT that you can't call ExternalInterface callbacks from javascript when the SWF is hidden (although that is also true). The problem IS that after showing the SWF again, the ExternalInterface callbacks are gone.

    Oh, and by the way, the visibility of the SWF does affect LocalConnection calls (at least in IE6). I tried many, many different ways of working around the problem and the LocalConnection approach was one of the things that I tried. The LocalConnection approach did resolve one level of issues that I was having with hiding and showing divs/iframes that contain SWFs with ExternalInterface callbacks, but I eventually ran into the same problem again in a different place. The solution that I mentioned above ended up being the best option for resolving all of my issues.
    • CommentAuthorwarnickr
    • CommentTimeMar 3rd 2008
     
    One more thing. After re-reading my comments above I realized that I didn't make it clear that the button click has an onclick handler that actually hides/shows the divs/iframes. It's probably obvious, but I thought that I would make sure that I was clear.
    • CommentAuthorAran
    • CommentTimeMar 4th 2008
     
    @warnickr - Thanks for your detailed replies.

    Unfortunately, my understanding is that once you hide the flash file, all external interface callbacks are broken/gone. So even if you manage to re-show you file in some way, it will no longer react properly. I am not aware of a solution to this other than using an iframe to completely unload/reload the swf and re-initializing the externalInterface calls.

    Can you make you flash file appear that it is gone without actually hiding it (a frame with no artwork on it or something) ? I am unsure of your design of your app/page, so I am not sure if this is a solution or not.

    Anyone else have any other thoughts / experiences?


    Kind regards,
    Aran
    • CommentAuthorwarnickr
    • CommentTimeMar 7th 2008
     
    I used an iframe in the case I described above and avoid the reloads by using browser specific code. IE is able to avoid reloads by toggling between display:none and display:block, but other browsers aren't. For Firefox and Safari, I use the visibility, width, and height styles to hide and show the iframe. I had this working prior to running into the problem with IE losing the callbacks. The work-around that I described above was the last step in being able to toggle between multiple SWFs across all the major browsers without breaking callbacks.
    • CommentAuthorAran
    • CommentTimeMar 7th 2008
     
    Well done on getting a solution happening. Don't you love designing for cross browser support ? :)

    A