banner
李大仁博客

李大仁博客

天地虽大,但有一念向善,心存良知,虽凡夫俗子,皆可为圣贤。

用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,target) 方法,第一个参数是 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 ; // 定义要打开的 URL
private var target; // 打开方式
public function setUrl(str)
{
this.url = str;
}
public function getUrl()
{
return this.url;
}
public function setTarget(str)
{
this.target = str;
}
public function getTarget()
{
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 = "";
xmlCall += url;
xmlCall += "";
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 调用使用了如下规则:

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

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

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.