如果你想在用户关闭浏览器时做一些额外工作,你可以尝试我这一段JS代码,它监听了以下几种关闭的情况:
1. 浏览器的关闭按钮
2. Alt+F4
3. Alt+Space弹出系统菜单后,选择关闭
4. 鼠标点击程序窗口顶部,弹出系统菜单后,选择关闭
5. 系统任务栏右键程序条弹出系统菜单,选择关闭
测试环境: XP, IE6, Firefox, 其它版本的IE未测,但应该也OK
思路:
1. 监听Window的beforeunload事件,
2. 为避免刷新页面产生的beforeunload, 这里只简单的禁用了F5功能
3. 监听Alt+F4 和 Alt+Space
4. 监听Mouse是否在有效用户区域内,本来isMouseInDocX是不用的,但因为Firefox选择了关闭选项后,又落在有效用户区域内,所以在记录鼠标点击时的isMouseInDoc状态(这似乎不需要,在下一个更新中去掉了,但依旧成功运行)
5. 因为Alt+Space改了isKeyInDocX但不能改回状态,所以利用MouseDown事件复位isKeyInDocX
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript">
function runBeforeCloseWindow(callback) {
// mointor the Alt+F4 and Alt+Space shortcut
var KEY_SPACE = 32;
var KEY_F4 = 115;
var KEY_F5 = 116;
// isMouseInDoc indicate if the beforeunload is to close the window
var isMouseInDoc = false;
// isMouseInDocX indicate the state when mousedown
var isMouseInDocX = false;
document.observe("mouseover", function(event) {
isMouseInDoc = true;
});
document.observe("mouseout", function(event) {
isMouseInDoc = false;
});
document.observe("mousedown", function(event) {
isMouseInDocX = isMouseInDoc;
isKeyInDocX = true;
});
// isKeyInDocX indicate if the beforeunload is trigger from Alt+F4/Alt+Space
var isKeyInDocX = false;
document.observe("keydown", function(event) {
isKeyInDocX = true;
if (event.altKey && KEY_F4 == event.keyCode) {
isKeyInDocX = false;
}
if (event.altKey && KEY_SPACE == event.keyCode) {
isKeyInDocX = false;
}
if (KEY_F5 == event.keyCode) {
event.stop();
event.keyCode = 0; // this is important for IE
}
});
Event.observe(window, "beforeunload", function(event) {
if(!isMouseInDocX || !isKeyInDocX) {
if (typeof callback == 'function') callback();
}
});
}
runBeforeCloseWindow(function(event) {
alert("close window");
});
</script>
|
// 2010/05/18
上面这个Script还有问题,当Alt+Space后,再点击关闭按钮时
重整后的代码如下
<script type="text/javascript" src="../script/prototype.js"></script>
<script type="text/javascript">
function runBeforeCloseWindow(callback) {
// mointor the Alt+F4 and Alt+Space shortcut
var KEY_SPACE = 32;
var KEY_F4 = 115;
var KEY_F5 = 116;
// isMouseInDoc indicate if the beforeunload is to close the window
var isMouseInDoc = false;
// isMouseInDocX indicate the state when mousedown
var isMouseInDocX = false;
document.observe("mouseover", function(event) {
isMouseInDoc = true;
});
document.observe("mouseout", function(event) {
isMouseInDoc = false;
isMouseInDocX = isMouseInDoc; // update the state when mouseout
});
document.observe("mousedown", function(event) {
isMouseInDocX = isMouseInDoc;
});
// isKeyInDocX indicate if the beforeunload is trigger from Alt+F4/Alt+Space
var isKeyInDocX = false;
document.observe("keydown", function(event) {
isKeyInDocX = true;
if (event.altKey && KEY_F4 == event.keyCode) {
isKeyInDocX = false;
}
if (event.altKey && KEY_SPACE == event.keyCode) {
isKeyInDocX = false;
}
if (KEY_F5 == event.keyCode) {
event.stop();
event.keyCode = 0; // this is important for IE
}
});
Event.observe(window, "beforeunload", function(event) {
if(!isMouseInDocX || !isKeyInDocX) {
if (typeof callback == 'function') callback();
}
});
}
runBeforeCloseWindow(function(event) {
alert("close window");
});
</script>
|
因为上面的代码没有考虑到Ctrl+W,Alt+F...可能关闭的情况,
整改思路, 简化为:
1. 当MouseOut时,标志当前窗口是可能也可以被关闭的
2. 当KeyDown且按下Alt/Ctrl时,标志当前窗口是可能也可以被关闭的
3. 必要的复位:
MouseDown, 如果此事件触发,则表示用户鼠标操作在当前窗口中,则isKeyInDoc应复位
KeyDown, 如果此事件触发,则表示用户键盘操作在当前窗口中,则isMouseInDoc应复位
但当测试Ctrl+W时,发现beforeunload可能被多次触发,故加上一个仅执行一次的标志callbackCount.
代码如下:
<script type="text/javascript" src="../script/prototype.js"></script>
<script type="text/javascript">
function runBeforeCloseWindow(callback) {
// isMouseInDoc indicate if the beforeunload is able to close the window
var isMouseInDoc = false;
document.observe("mouseover", function(event) {
isMouseInDoc = true;
});
document.observe("mouseout", function(event) {
isMouseInDoc = false;
});
// mointor the Alt & Ctrl Func key, which may enable close-window in the menu or shortcuts
// isKeyInDoc indicate if the beforeunload is able to close the window
var isKeyInDoc = false;
document.observe("keydown", function(event) {
isKeyInDoc = true;
if (event.altKey || event.ctrlKey) {
isKeyInDoc = false;
}
});
// here clear the lazy-update for non-sync isKeyInDoc and isMouseInDoc
document.observe("mousedown", function(event) {
isKeyInDoc = true;
});
document.observe("keydown", function(event) {
isMouseInDoc = true;
});
var callbackCount = 1;
Event.observe(window, "beforeunload", function(event) {
// let the handle run one and only one time.
if (1<callbackCount++) return ;
if (!isMouseInDoc || !isKeyInDoc) {
if (typeof callback == 'function') callback();
}
});
}
// block refresh key F5 and other that trigger beforeunload event
function blockOtherBeforeUnloadEvent() {
var KEY_F5 = 116;
document.observe("keydown", function(event) {
if (KEY_F5 == event.keyCode) {
event.stop();
event.keyCode = 0; // this is important for IE
}
});
}
runBeforeCloseWindow(function(event) {
alert("close window");
});
</script>
|
多谢观看^_^