在客户端的当前页判断当前页是否关闭很难实现 而且考虑到打开多个窗口的情况 必须至少有一个页面做为执行程序的宿主来判断页面状态 所以可以应用主窗体+JS全局变量的方式 实现方法如下:
1 定义一个JS文件my.js 和一个宿主页 check.htm
2 my.js 主要包含两个全局变量 两个全局方法
变量1 var wTop 保存宿主页对象
变量2 var wArray=new Array() 为数组类型 用以保存已打开窗口的句柄
方法1 checkWin()为布尔类型 用于检测wArray中是否还有数据 当全部wArray[i].closed为true即所有窗口均关闭时 返回false 否则返回true
方法2 addWin()用于向wArray中添加新打开的窗口句柄
3 在其它任意页引用my.js 并在onload事件中执行 addWin和checkTop方法(注意 这两个方法的执行执行顺序不能颠倒)
4 静态页check.htm作为js检测程序的宿主 引用my.js 在check.htm中以setTimeout方法定时执行checkWin() 当它返回true时不做任何操作 当返回false时便通过JS脚本向服务器回传窗口已关闭事件 服务器再做相应处理 当然此check.htm已经没有存在意义
以上解决方式的优点是所有判断都在客户端执行 仅最后一次向服务器回传(这正是我们想要的) 缺点是总要打开一个看似没有用处的窗口 让
用户不知所云 但可以把此窗口隐藏在屏幕区外
addWin()中主要代码如下所示
if(wTop==null)
{
wArray[wArray.length]=self; //当前页记录到数组列表中
self.focus(); //页面焦点应该在当前页 这句代码必须放在下后两句之前 以防止客户端IE阻止弹出窗口也不会
出错 当然 如果弹出窗口不成功 此方法也失效了
wTop=window.open("test.htm","top","width=10,height=10");
wTop.moveTo(-200,-200); //隐藏到屏幕区外
}
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)
{
//所有窗口已经关闭
return false;
}
else
{
return true;
}
check.htm页中js如下示
function check()
{
if(!checkWin())
{
//此处填写将状态回传到服务器
//的一此处理
window.close(); //关闭宿主页
}
else
{
setTimeout("check()",5000); //隔5秒检测一次
}
}
window.attachEvent("onload",check);
这样是每5秒做一次判断 其实可以精确到每一秒做一次判断 这样应当已经算得上精确了 而且几乎不会给客户端带来任何负担(举个例子 它甚至比一个简单的显示时间的js脚本占用资源还要少)
写到这才发现原来也可以将js做一些修改 直接引用这个js文件 就不用每个页都attachEvent了 |