上一篇日誌講到 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