是否有任何跨浏览器的JavaScript/jQuery代码来检测浏览器或浏览器标签是否正在关闭,但不是由于链接被单击?
当前回答
我找到了一个方法,在我所有的浏览器上都能运行。
测试在以下版本: Firefox 57, Internet Explorer 11, Edge 41,最新的Chrome浏览器之一(无法显示我的版本)
注意:onbeforeunload火灾如果你离开页面以任何可能的方式(刷新,关闭浏览器,重定向,链接,提交..)。如果只希望它在浏览器关闭时发生,只需绑定事件处理程序。
$(document).ready(function(){
var validNavigation = false;
// Attach the event keypress to exclude the F5 refresh (includes normal refresh)
$(document).bind('keypress', function(e) {
if (e.keyCode == 116){
validNavigation = true;
}
});
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function() {
validNavigation = true;
});
window.onbeforeunload = function() {
if (!validNavigation) {
// -------> code comes here
}
};
});
其他回答
window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "tab close";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
sendkeylog(confirmationMessage);
return confirmationMessage; //Webkit, Safari, Chrome etc.
});
由于没有人提到它(8年多以后):WebSocket可以是检测关闭选项卡的另一种有效方法。只要选项卡打开并指向主机,客户端就能够保持到主机的活动WebSocket连接。
警告:请注意,这个解决方案只适用于WebSocket不需要任何额外的重大开销的项目。
在合理的超时时间内(例如2分钟),服务器端可以在WebSocket断开连接后确定客户端已经离开,并执行所需的任何操作,例如删除上传的临时文件。(在我非常专业的用例中,我的目标是在WebSocket连接断开和所有CGI/FastCGI活动终止三秒钟后终止本地主机应用服务器-任何其他保持活动的连接都不会影响我。)
我有问题让onunload事件处理程序正确地与信标一起工作(正如这个答案所推荐的)。关闭选项卡似乎不会触发信标,而打开选项卡则会以可能导致问题的方式触发信标。WebSocket更干净地解决了我遇到的问题,因为连接关闭的时间与选项卡关闭的时间大致相同,在应用程序中切换页面只是在延迟窗口内打开一个新的WebSocket连接。
我的方法是:
使用onpopstate监听url中的变化,并将sessionStorage变量设置为1 监听页面加载并将sessionStorage变量设置为0 在beforeunload上,检查变量是否为0。如果是这样,这意味着用户正在关闭而不是改变url。
这仍然是一条迂回的路,但对我来说是有意义的
我需要在浏览器或选项卡关闭时自动注销用户,而不是当用户导航到其他链接时。我也不希望在发生这种情况时显示确认提示。在与这个问题斗争了一段时间后,尤其是在IE和Edge上,以下是我在基于这个答案的方法之后所做的(检查了在IE 11、Edge、Chrome和Firefox上的工作)。
首先,在JS中的beforeunload事件处理程序中启动服务器上的倒计时计时器。ajax调用需要同步,IE和Edge才能正常工作。你还需要使用return;防止确认对话框像这样显示:
window.addEventListener("beforeunload", function (e) {
$.ajax({
type: "POST",
url: startTimerUrl,
async: false
});
return;
});
启动计时器将cancelLogout标志设置为false。如果用户刷新页面或导航到另一个内部链接,服务器上的cancelLogout标志将被设置为true。一旦计时器事件失效,它将检查cancelLogout标志,以查看注销事件是否已取消。如果计时器已经取消,那么它将停止计时器。如果浏览器或选项卡被关闭,那么cancelLogout标志将保持为false,事件处理程序将注销用户。
实现注意:我使用的是ASP。NET MVC 5和我取消注销在一个重写的Controller.OnActionExecuted()方法。
简单的解决方案
window.onbeforeunload = function () {
return "Do you really want to close?";
};