[ActionScript]用AS+JS实现IE等浏览器的强制弹出窗口附源代码

ActionScript,JavaScript,源代码,Flash

上一篇日志讲到CG朋友要求对单独页面实现分别多种连接打开效果的实现
,里面提到IE或者其他的工具栏(yahoo,google)等可以拦截弹出窗口而
无法在用户浏览器实现的问题,除了上次提到的将open方法改成ShowMo
delDialog方法之外,CG今天分享一个用Flash/FLEX AS实现的强制用户
浏览器弹出窗口的方法,这种方法CG感觉是一种很流氓的方法,因为几乎
所有的用户浏览器都安装了Flash的PlugIn或者ActiveX,而用SWF文件来
实现弹出窗口那浏览器和工具栏也是没有办法的,而目前大部分的用户的
尤其是FF用户一般在浏览器安全上是允许访问网络的。

因为AS有2和3两个版本,CG这里只具体介绍AS3版本,AS2的实现比较
简单,大家只要新建一个AS2的flash文件然后在动作中增加如下代码即可

getURL("http://www.demo.com");

然后生成相应的swf文件,然后简单发布一下即可,这种方法很简单,但是
大家要注意的是flash因为需要考虑安全问题,弹出的新窗口的URL必须要跟
弹窗的URL的域相同,比如http://www.demo.com/a.html弹出的就只能是
demo.com所在域的页面,否则会提示脚本错误。

这种方式在IE6一下版本可用,但是到了IE7+的话,请大家注意一下设置
将flash播放控件的wmode设置为window,这种模式是非DOM托管模式
就是跟其所在的容器无关的模式

下面CG具体讲怎样用AS3版本实现,AS3下面getURL方法被修改为flash.net
包下的navigateToURL(url:String,target:String)方法,第一个参数是URL,
第二个则是打开方式了,如果是弹窗则是”_blank”,为了调用更方便CG写
了如下的AS3代码,使用了flash的ExternalInterface接口来调用让flash
可以更灵活的实现弹出窗口,为了方便调试,CG使用了在客户端调用实现
的方式,大家可以清楚的看到AS和JS之间的相互调用的过程,如果大家要
放在自己站上,可以考虑用读取XML方式来实现,客户端将无法看到调用
过程,这里代码省略。

另外大家需要注意的是flash的安全性问题,AS跨域访问需要在客户端允许
要求上面已经说明,只是AS3下有更详细的设置。

以下是AS3代码,使用FLEX3调试:

package {
  import flash.display.Sprite;
  import flash.external.ExternalInterface;
  import flash.net.*;
 
  public class IePopup extends Sprite
  {
    private var url:String ;  //定义要打开的URL
    private var target:String;  //打开方式
    public function setUrl(str:String):void
    {
      this.url = str;  
    }
    public function getUrl():String
    {
      return this.url;
    }
    public function setTarget(str:String):void
    {
      this.target = str;
    }
    public function getTarget():String
    {
      return this.target;
    }
    //constructor
    public function IePopup()
    {
      this.register();
      this.popup();  
    }
 
    //register
    private function register():void
    {
      //监听外部调用,函数名为jsCall,回调函数名为jsCall
      ExternalInterface.addCallback("jsCall",jsCall);
    }
    //popup
    private function popup():void
    {
      var targetURL:URLRequest = new URLRequest(this.getUrl());
        navigateToURL(targetURL,this.getTarget());  //调用弹出窗口
    }
 
    //jsCall
    public function jsCall(url:String,tar:String = '_blank'):void
    {
      if(url.length==0||tar=='')
        return;
      this.setUrl(url);  //设置字符串
      if(tar.length==0||tar=='')
        this.target=='_blank';  //设置默认为新窗口
      this.setTarget(tar);
      this.popup();//弹窗
    }  
  }
}

代码说明:定义了两个变量用来获取和设置url和target参数,当构造flash
类将自动注册用来获取参数的函数名和回调方法名,在jsCall方法中获取来自
JS传递过来的两个参数,判断之后弹出窗口。

以下是部分JS代码:

var ready=false;  
//Flash activeX is ready?
function IsReady(){
  return ready;
}
//Flash activeX ready
function Ready(){
  ready=true;
}
//use Flash object
function domJsCall(url) {
  window['IePopup'].jsCall(url);  //for IE
  //document['IePopup'].jsCall(url); //for others
}
//use XML
function xmlJsCall(url){
  var xmlCall = "<invoke name=\"jsCall\" returntype=\"XML\"><arguments><string>";
	 xmlCall += url;
	 xmlCall += "</string></arguments></invoke>";
  window['IePopup'].CallFunction(xmlCall);
}
function jsCall(url){
  if(IsReady()){
	 //two methods
	 xmlJsCall(url);  //XML
	 //domJsCall(url); //dom
  }
}

代码说明:这里定义了一个变量用于检查Flash对象是否加载成功,定义了
一个jsCall(url)用户客户端调用,CG在这里定义了两种调用方式,DOM方式
和XML方式,其中的XML方式可以用于低版本浏览器和Flash对象,DOM方式比
较简单,但是实质是一样的,Flash与其容器时异步通信的,所以DOM方式调
用是DOM对象屏蔽了XML通信过程来实现的,CG在这里推荐大家使用XML方式
灵活性比较大一点,XML调用使用了如下规则:

<invoke name="functionName" returntype="typeName">
	<arguments>
		<string></string>
	</arguments>
</invoke>

其中arguments的子节点是参数列表和类型

以上例子所有源代码下载地址:
http://www.fantaci.org/code/popup/src.zip

Comments (6)

DDR物语July 24th, 2009 at 12:12 pm

各位同仁,不好意思了,前段时间是因为博客IP被和谐了,所以不能访问。现在访问正常了,以后常来往呀。

小桥流水人家July 24th, 2009 at 4:08 pm

出差归来,您老一切可还安好。。。

kiviJuly 30th, 2009 at 10:01 pm

为什么我的域名没用了啊

小桥流水人家August 5th, 2009 at 11:34 am

最近迷上ruby..

CGAugust 7th, 2009 at 12:08 pm

嘎嘎,ruby相比于python来说语法更易学,使用更简单哦

MOGPSeptember 23rd, 2009 at 9:10 pm

[news][ActionScript]用AS+JS实现IE等浏览器的强制弹出窗口附源代码…

志讲到CG朋友要求对单独页面实现分别多种连接打开效果的实现
,里面提到IE或者其他的工具栏(yahoo,google)等可以拦截弹出窗口而
无法在用户浏览器实现的问题,除了上次提到的将open方法…

Leave a comment

Your comment