views:

390

answers:

2

I would like to open external URLs from within my Flash project. I typically use something like this:

getURL("javascript:newwin=window.open('http://someurl.com','','');");

But, if Javascript isn't available (in cases where the SWF is not embedded in HTML) then this will fail. How can I detect whether Javascript is available? If it isn't available, I'd probably just use getURL and give it the direct URL, although I only want to do this if using the Javascript method isn't possible. Thanks!

+5  A: 

To accomplish what you're describing, the best way is to have Flash invoke a JavaScript function called "pingJavaScript". If JavaScript is running, that JavaScript function will then call a function on the Flash movie called "receiveJSNotification". So in your Flash movie, if that method gets called, you know JS is running.

To enable robust communication between a Flash movie and JavaScript, include this at the top of an Actionscript on the first frame of your movie:

import flash.external.ExternalInterface;
import flash.events.Event;

Add a function to receive a "yes, I'm alive" from JavaScript:

var js_available = false;

function receiveJSNotification(str:String):void {
 _root.js_available = true;
}

ExternalInterface.addCallback("notifyFlash", receiveJSNotification);
ExternalInterface.call("pingJavaScript", null);

In JavaScript:

function pingJavaScript()
{
    var movie = getFlash();
    movie.notifyFlash();
}

function getFlash()
{
    var movie = null;
    if (navigator.appName.indexOf('Microsoft') != -1) {
        movie = window['flashmovie'];
    } else {
        movie = document['flashmovie'];
    }
    return movie;
}
Rex M
Interesting approach. This complicates things, but if that is the best method, I may adopt it. Will this work in Actionscript 2? Thanks!
ZenBlender
Yes, it does work with AS2. I have used it for a number of interactions between JS and Flash.
Rex M
What if I just want to know if JS is *available* but don't have JS code in the HTML for this detection? Someone might use my SWF by opening it in the Flash Player, or might drop it onto a blank HTML doc. I may not be able to set up pingJavaScript() and getFlash() but can still use JS in that case.
ZenBlender
That is not possible. Flash would have to ask the browser directly, and browser publishers do not have any kind of public property we can access that says whether JS is available.
Rex M
This may be verging on silly, but you might write some javascript that would create the pingJavaScript and getFlash functions, and then call them?Something like this (but with actual functionality):ExternalInterface.call("eval", "function foo(){bar();}function bar(){alert('bar');};foo();");
Andrew
@Andrew that's a good idea
Rex M
Yea, I might try the inline function declaration in an ExternalInterface call as you suggested. Thanks! (It is silly, by the way, but if it works, that won't matter!)
ZenBlender
+3  A: 

I find that there is actually a much easier way to accomplish this:

public function isThereJavaScript():Boolean{
    return Boolean(ExternalInterface.call("window.location.href.toString"));
}

This requires no JavaScript back-end. It just works consistently. If there is the ability to call JavaScript, that means that there has to be a window property, which will have a non-null location.href. ExternalInterface is also available for both AS2 and AS3.

Christopher W. Allen-Poole