在客戶端的當前頁判斷當前頁是否關閉很難實現(xiàn) 而且考慮到打開多個窗口的情況 必須至少有一個頁面做為執(zhí)行程序的宿主來判斷頁面狀態(tài) 所以可以應用主窗體+JS全局變量的方式 實現(xiàn)方法如下:
1 定義一個JS文件my.js 和一個宿主頁 check.htm
2 my.js 主要包含兩個全局變量 兩個全局方法
變量1 var wTop 保存宿主頁對象
變量2 var wArray=new Array() 為數(shù)組類型 用以保存已打開窗口的句柄
方法1 checkWin()為布爾類型 用于檢測wArray中是否還有數(shù)據(jù) 當全部wArray[i].closed為true即所有窗口均關閉時 返回false 否則返回true
方法2 addWin()用于向wArray中添加新打開的窗口句柄
3 在其它任意頁引用my.js 并在onload事件中執(zhí)行 addWin和checkTop方法(注意 這兩個方法的執(zhí)行執(zhí)行順序不能顛倒)
4 靜態(tài)頁check.htm作為js檢測程序的宿主 引用my.js 在check.htm中以setTimeout方法定時執(zhí)行checkWin() 當它返回true時不做任何操作 當返回false時便通過JS腳本向服務器回傳窗口已關閉事件 服務器再做相應處理 當然此check.htm已經(jīng)沒有存在意義
以上解決方式的優(yōu)點是所有判斷都在客戶端執(zhí)行 僅最后一次向服務器回傳(這正是我們想要的) 缺點是總要打開一個看似沒有用處的窗口 讓
用戶不知所云 但可以把此窗口隱藏在屏幕區(qū)外
addWin()中主要代碼如下所示
if(wTop==null)
{
wArray[wArray.length]=self; //當前頁記錄到數(shù)組列表中
self.focus(); //頁面焦點應該在當前頁 這句代碼必須放在下后兩句之前 以防止客戶端IE阻止彈出窗口也不會
出錯 當然 如果彈出窗口不成功 此方法也失效了
wTop=window.open("test.htm","top","width=10,height=10");
wTop.moveTo(-200,-200); //隱藏到屏幕區(qū)外
}
else
{
wArray[wArray.length]=self;
}
上面的方法只能隱藏IE窗口 它仍在任務欄存在
checkWin主要代碼如下
var i;
var count=0;
for(i=0;i<wArray.length;i++)
{
if(wArray[i].closed)
{
count++;
}
}
if(wArray.length==count)
{
//所有窗口已經(jīng)關閉
return false;
}
else
{
return true;
}
check.htm頁中js如下示
function check()
{
if(!checkWin())
{
//此處填寫將狀態(tài)回傳到服務器
//的一此處理
window.close(); //關閉宿主頁
}
else
{
setTimeout("check()",5000); //隔5秒檢測一次
}
}
window.attachEvent("onload",check);
這樣是每5秒做一次判斷 其實可以精確到每一秒做一次判斷 這樣應當已經(jīng)算得上精確了 而且?guī)缀醪粫o客戶端帶來任何負擔(舉個例子 它甚至比一個簡單的顯示時間的js腳本占用資源還要少)
寫到這才發(fā)現(xiàn)原來也可以將js做一些修改 直接引用這個js文件 就不用每個頁都attachEvent了 |