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

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。