可悲的是,这不是一个要解决的简单问题。但这是可以完成的。下面的答案是由许多不同的 SO 答案合并而成的。
简单部分:
知道窗户正在被破坏。您可以使用onunload 事件句柄来检测这一点。
棘手的部分:
检测它是刷新、链接跟随还是所需的窗口关闭事件。删除链接和表单提交很容易:
var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });
$(window).bind('beforeunload', function(eventObject) {
var returnValue = undefined;
if (! inFormOrLink) {
returnValue = "Do you really want to close?";
}
eventObject.returnValue = returnValue;
return returnValue;
});
穷人的解决方案
检查event.clientY 或event.clientX 以确定点击了什么来触发事件。
function doUnload(){
if (window.event.clientX < 0 && window.event.clientY < 0){
alert("Window closed");
}
else{
alert("Window refreshed");
}
}
Y 轴不起作用,因为它对于单击重新加载或选项卡/窗口关闭按钮是负面的,而当使用键盘快捷键重新加载(例如 F5、Ctrl-R、...)和关闭窗口(例如Alt-F4)。 X 轴没有用,因为不同的浏览器有不同的按钮位置。但是,如果您受到限制,那么通过一系列 if-else 运行事件坐标可能是您最好的选择。请注意,这肯定不可靠。
涉及的解决方案
(取自Julien Kronegg)使用HTML5的本地存储和客户端/服务器AJAX通信。警告:这种方法仅限于支持 HTML5 本地存储的浏览器。
在您的页面上,将onunload 添加到以下处理程序的窗口
function myUnload(event) {
if (window.localStorage) {
// flag the page as being unloading
window.localStorage['myUnloadEventFlag']=new Date().getTime();
}
// notify the server that we want to disconnect the user in a few seconds (I used 5 seconds)
askServerToDisconnectUserInAFewSeconds(); // synchronous AJAX call
}
然后将onloadon主体添加到以下处理程序
function myLoad(event) {
if (window.localStorage) {
var t0 = Number(window.localStorage['myUnloadEventFlag']);
if (isNaN(t0)) t0=0;
var t1=new Date().getTime();
var duration=t1-t0;
if (duration<10*1000) {
// less than 10 seconds since the previous Unload event => it's a browser reload (so cancel the disconnection request)
askServerToCancelDisconnectionRequest(); // asynchronous AJAX call
} else {
// last unload event was for a tab/window close => do whatever
}
}
}
在服务器上,将断开连接请求收集到一个列表中,并设置一个
定期检查列表的计时器线程(我使用过
每 20 秒)。一旦断开连接请求超时(即 5
秒过去了),断开用户与服务器的连接。如果一个
同时收到断开连接请求取消,
从列表中删除相应的断开连接请求,以便
用户不会被断开。
如果您想区分
选项卡/窗口关闭事件和后续链接或提交的表单。你刚才
需要在每个包含链接的页面上放置两个事件处理程序
和表单以及每个链接/表单登录页面。
结束评论(双关语):
由于您想在窗口关闭时删除 cookie,我假设这是为了防止它们在未来的会话中被使用。如果这是一个正确的假设,那么上述方法将很有效。您将无效的cookie保留在服务器上(一旦客户端断开连接),当客户端创建新会话时,JS将默认发送cookie,此时您知道它来自较旧的会话,删除它并可选地提供在客户端上设置新的。