Opening External Links from AS3
So, you probably know that opening external links from inside AS3 is an issue. Depending on the browser, the “_blank” new window openings are blocked as though they were pop ups.
There are many blog entries and forum entries on the web discussing ways to deal with this, some more useful than others; many do not encompass all browsers; many still deal with AS2, etc, etc.
After much, much searching, reading, and experiments, I wanted to post the resolution that I currently believe works the best.
When it all comes down to it, this is the guy that had the solution: “Jason the Saj”. Blog page is here. (http://thesaj.wordpress.com/2008/02/12/the-nightmare-that-is-_blank-part-ii-help/)
And here is the final code that I use personally (in a static method that I never have to think about again, of course).
import flash.external.ExternalInterface; public static function openWindow(url:String, _window:eURLTarget=null, features:String=""):void { var window:String = (_window == null) ? eURLTarget.BLANK.toString() : _window.toString() ; //Sets function name into a variable to be executed by ExternalInterface. //Otherwise Flex will try to find a local function or value by that name. var WINDOW_OPEN_FUNCTION:String = "window.open"; var myURL:URLRequest = new URLRequest(url); var browserName:String = getBrowserName(); //If browser is Firefox, use ExternalInterface to call out to browser //and launch window via browser's window.open method. if(browserName == "Firefox"){ ExternalInterface.call(WINDOW_OPEN_FUNCTION, url, window, features); } //If IE, else if(browserName == "IE"){ ExternalInterface.call("function setWMWindow() {window.open('" + url + "');}"); } //If Safari else if(browserName == "Safari"){ navigateToURL(myURL, window); } //If Opera else if(browserName == "Opera"){ navigateToURL(myURL, window); } //Otherwise, use Flex's native 'navigateToURL()' function to pop-window. //This is necessary because Safari 3 no longer works with the above ExternalInterface work-a-round. else{ navigateToURL(myURL, window); } /*Alternate methodology... var popSuccess:Boolean = ExternalInterface.call(WINDOW_OPEN_FUNCTION, url, window, features); if(popSuccess == false){ navigateToURL(myURL, window); }*/ } private static function getBrowserName():String { var browser:String; //Uses external interface to reach out to browser and grab browser useragent info. var browserAgent:String = ExternalInterface.call("function getBrowser(){return navigator.userAgent;}"); //Determines brand of browser using a find index. If not found indexOf returns (-1). if(browserAgent != null && browserAgent.indexOf("Firefox") >= 0) { browser = "Firefox"; } else if(browserAgent != null && browserAgent.indexOf("Safari") >= 0){ browser = "Safari"; } else if(browserAgent != null && browserAgent.indexOf("MSIE") >= 0){ browser = "IE"; } else if(browserAgent != null && browserAgent.indexOf("Opera") >= 0){ browser = "Opera"; } else { browser = "Undefined"; } return (browser); }
You’ll notice that, in my useage, I have a _window:eURLTarget argument. I hate haveing to remember what the possible targets are. Hence the “enum”. Here’s the code for that.
public class eURLTarget { public static const BLANK:eURLTarget = new eURLTarget("_blank"); public static const PARENT:eURLTarget = new eURLTarget("_parent"); public static const SELF:eURLTarget = new eURLTarget("_self"); public static const TOP:eURLTarget = new eURLTarget("_top"); public function toString():String{return this._string;} private var _string:String; public function eURLTarget(string:String){if(locked){new BrSkError(eErrorType.ENUM_INSTANTIATION, this);} _string=string;} private static var locked:Boolean = false; {locked = true;} }
You’ll have to replace the…
new BrSkError(eErrorType.ENUM_INSTANTIATION, this);
…with your own error-throwing methodology.
On to an additional, but related point. I have a client who needed a “Submit your email address to sign up for our Newsletter” section on their site. They use a service that accepts these email addresses and databases them, etc, etc. Example of doing this is below as well.
Typical usage of the above code would be something like:
openWindow( "http://www.broadskies.com" ); So, if I need to send variables, then... openWindow( "http://www.broadskies.com?myvariable=hello&myothervariable=world" );
… and the “& amp ;” in the above line should only be “&”. I can’t get WordPress to stop changing it.
30. June 2008 at 13:38
Much obliged on the compliment.
BTW, in my personal use I broke the process into classes. (Figured it might be useful to determine browser for other tasks as well.)
But in posting to my blog, I endeavored to keep it as simple as possible.
30. June 2008 at 13:59
And much obliged on your commenting, theSaj. Good point. The above “private static function getBrowserName():String”, could be changed to “public” to perhaps accomplish something similar.
Personally, I keep a small few of these common-use functions in a single class, all marked public static.
Thanks again!