Home > 语言编程 > 用AS+JS实现IE等浏览器的强制弹出窗口源代码

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

上一篇日志讲到CG朋友要求对单独页面实现分别多种连接打开效果的实现,里面提到IE或者其他的工具栏(yahoo,google)等可以拦截弹出窗口而无法在用户浏览器实现的问题,除了上次提到的将open方法改成ShowModelDialog方法之外,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.lidaren.com/code/popup/src.zip

  1. July 24th, 2009 at 12:12 | #1

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

  2. July 24th, 2009 at 16:08 | #2

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

  3. kivi
    July 30th, 2009 at 22:01 | #3

    为什么我的域名没用了啊

  4. August 5th, 2009 at 11:34 | #4

    最近迷上ruby..

  5. August 7th, 2009 at 12:08 | #5

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

  6. June 22nd, 2012 at 22:31 | #6

    我下了源码,但弹不出是怎么回事呢>

    • CG
      July 14th, 2012 at 13:19 | #7

      弹出不了窗口应该是以下问题引起的
      1,这些代码在本地运行时由于flash的安全问题不能实现效果,应该是发布在服务端的代码才可以
      2,flash如果没有打开跨域处理,只能弹出本域名下的页面

  1. September 23rd, 2009 at 21:10 | #1
You must be logged in to post a comment.