如何捕获浏览器窗口关闭事件?

我想捕获浏览器窗口/标签关闭事件。 我在 jQuery 中尝试了以下方法:

jQuery(window).bind(
"beforeunload",
function() {
return confirm("Do you really want to close?")
}
)

但它也适用于表单提交,这不是我想要的。我想要一个只在用户关闭窗口时触发的事件。

469347 次浏览

也许您可以处理 OnSubmit 并设置一个标志,以便稍后在 OnBeforeUnload 处理程序中检查该标志。

也许只需要在表单的 submit事件处理程序中解除 beforeunload事件处理程序的绑定:

jQuery('form').submit(function() {
jQuery(window).unbind("beforeunload");
...
});

无论用户出于何种原因离开页面,beforeunload事件都会触发。

例如,如果用户提交表单、单击链接、关闭窗口(或选项卡) ,或者使用地址栏、搜索框或书签进入新页面,那么它将被触发。

你可以用下面的代码排除表单提交和超链接(其他框架除外) :

var inFormOrLink;
$('a').on('click', function() { inFormOrLink = true; });
$('form').on('submit', function() { inFormOrLink = true; });


$(window).on("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})

对于超过1.7的 jQuery 版本,可以这样做:

var inFormOrLink;
$('a').live('click', function() { inFormOrLink = true; });
$('form').bind('submit', function() { inFormOrLink = true; });


$(window).bind("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})

live方法不适用于 submit事件,因此如果添加新表单,也需要将处理程序绑定到它。

请注意,如果不同的事件处理程序取消了提交或导航,那么如果以后窗口实际关闭,您将失去确认提示。您可以通过在 submitclick事件中记录时间,并检查 beforeunload是否发生在几秒钟之后来解决这个问题。

如果您的表单提交将它们带到另一个页面(正如我假设的那样,因此触发 beforeunload) ,您可以尝试将表单提交更改为 ajax 调用。这样,他们在提交表单时就不会离开您的页面,您可以根据自己的愿望使用 beforeunload绑定代码。

跟踪对我很有用;

 $(window).unload(function(event) {
if(event.clientY < 0) {
//do whatever you want when closing the window..
}
});

我的问题: ‘ onbefore unload’事件只有在提交(点击)次数为奇数时才会被触发。在 SO 中,我有来自相似线程的解决方案组合,以使我的解决方案能够正常工作。我的代码会说话。

<!--The definition of event and initializing the trigger flag--->




$(document).ready(function() {
updatefgallowPrompt(true);
window.onbeforeunload = WarnUser;
}


function WarnUser() {
var allowPrompt = getfgallowPrompt();
if(allowPrompt) {
saveIndexedDataAlert();
return null;
} else {
updatefgallowPrompt(true);
event.stopPropagation
}
}


<!--The method responsible for deciding weather the unload event is triggered from submit or not--->
function saveIndexedDataAlert() {
var allowPrompt = getfgallowPrompt();
var lenIndexedDocs = parseInt($('#sortable3 > li').size()) + parseInt($('#sortable3 > ul').size());


if(allowPrompt && $.trim(lenIndexedDocs) > 0) {
event.returnValue = "Your message";
} else {
event.returnValue = "   ";
updatefgallowPrompt(true);
}
}


<!---Function responsible to reset the trigger flag---->
$(document).click(function(event) {
$('a').live('click', function() { updatefgallowPrompt(false); });
});


<!--getter and setter for the flag---->
function updatefgallowPrompt (allowPrompt){ //exit msg dfds
$('body').data('allowPrompt', allowPrompt);
}


function getfgallowPrompt(){
return $('body').data('allowPrompt');
}

我使用了 Slaks 的答案,但是它并没有按照原来的方式工作,因为 onbefore 卸载 returValue 被解析为一个字符串,然后显示在浏览器的确认框中。这样就显示了值 true,就像“ true”一样。

只是使用返回工作。 这是我的密码

var preventUnloadPrompt;
var messageBeforeUnload = "my message here - Are you sure you want to leave this page?";
//var redirectAfterPrompt = "http://www.google.co.in";
$('a').live('click', function() { preventUnloadPrompt = true; });
$('form').live('submit', function() { preventUnloadPrompt = true; });
$(window).bind("beforeunload", function(e) {
var rval;
if(preventUnloadPrompt) {
return;
} else {
//location.replace(redirectAfterPrompt);
return messageBeforeUnload;
}
return rval;
})

对于一个跨浏览器的解决方案(在 Chrome21,IE9,FF15中测试过) ,可以考虑使用下面的代码,这是一个稍微调整过的 Slaks 代码版本:

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;
});

请注意,从 Firefox 4开始,“ Do you really want to close?”不显示。FF 只显示一个通用消息。请参阅 https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload中的注释

对于像 Telerik (比如 RadComboBox)和 DevExpress 这样出于各种原因使用 Anchor 标签的第三方控件,可以考虑使用下面的代码,它是 desm 代码的一个稍微调整过的版本,有一个更好的自定位锚标签选择器:

var inFormOrLink;
$('a[href]:not([target]), a[href][target=_self]').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;
});

在 jQuery 1.7中,。不推荐使用 live ()方法。使用。对()附加事件处理程序。旧版本 jQuery 的用户应该使用。优先于... 的委托()。现场直播

$(window).bind("beforeunload", function() {
return true || confirm("Do you really want to close?");
});

完整的或链接的

$(window).unbind();

核实一下。

function wopen_close(){
var w = window.open($url, '_blank', 'width=600, height=400, scrollbars=no, status=no, resizable=no, screenx=0, screeny=0');
w.onunload = function(){
if (window.closed) {
alert("window closed");
}else{
alert("just refreshed");
}
}
}
window.onbeforeunload = function () {
return "Do you really want to close?";
};
jQuery(window).bind("beforeunload", function (e) {
var activeElementTagName = e.target.activeElement.tagName;
if (activeElementTagName != "A" && activeElementTagName != "INPUT") {
return "Do you really want to close?";
}
})

不幸的是,无论是重新加载,新的页面重定向,或浏览器关闭事件将被触发。另一种方法是捕获触发事件的 id,如果它是 form,则不触发任何函数,如果它不是 form 的 id,则在页面关闭时执行您想要执行的操作。我不确定这是否也可以直接实现,而且很乏味。

您可以在客户关闭选项卡之前做一些小事情。但是,如果你的行动清单很大,标签关闭之前,它是完成你是无助的。你可以试试,但以我的经验,不要依赖它。

window.addEventListener("beforeunload", function (e) {
var confirmationMessage = "\o/";
/* Do you small action code here */
(e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage;                            //Webkit, Safari, Chrome
});

Https://developer.mozilla.org/en-us/docs/web/reference/events/beforeunload?redirectlocale=en-us&redirectslug=dom/mozilla_event_reference/beforeunload

我的答案旨在提供简单的基准。

如何

参见 @ Slaks 的回答

$(window).on("beforeunload", function() {
return inFormOrLink ? "Do you really want to close?" : null;
})

浏览器需要多长时间才能最终关闭您的页面?

每当用户关闭页面(x按钮或 CTRL + W) ,浏览器就会执行给定的 beforeunload代码,但不会无限期执行。唯一的例外是确认框(return 'Do you really want to close?) ,它将等待用户的响应。

Chrome : 2秒。
Firefox : ∞(或双击,或关闭)
Edge : ∞(或双击)
探险家11号 : 0秒。
Safari : < em > TODO

我们用来测试的方法是:

  • 带有请求日志的 Node.js Express 服务器
  • 下面是一个简短的 HTML 文件

它所做的就是在浏览器关闭页面之前(同步地)发送尽可能多的请求。

<html>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function request() {
return $.ajax({
type: "GET",
url: "http://localhost:3030/" + Date.now(),
async: true
}).responseText;
}
window.onbeforeunload = () => {
while (true) {
request();
}
return null;
}
</script>
</body>
</html>

Chrome 输出:

GET /1480451321041 404 0.389 ms - 32
GET /1480451321052 404 0.219 ms - 32
...
GET /hello/1480451322998 404 0.328 ms - 32


1957ms ≈ 2 seconds // we assume it's 2 seconds since requests can take few milliseconds to be sent.

也试试这个

window.onbeforeunload = function ()
{
if (pasteEditorChange) {
var btn = confirm('Do You Want to Save the Changess?');
if(btn === true ){
SavetoEdit();//your function call
}
else{
windowClose();//your function call
}
}  else {
windowClose();//your function call
}
};
var validNavigation = false;
jQuery(document).ready(function () {


wireUpEvents();
});


function endSession() {
// Browser or broswer tab is closed
// Do sth here ...
alert("bye");
}


function wireUpEvents() {
/*
* For a list of events that triggers onbeforeunload on IE
* check http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx
*/
window.onbeforeunload = function () {
debugger
if (!validNavigation) {
endSession();
}
}


// Attach the event keypress to exclude the F5 refresh
$(document).bind('keypress', function (e) {
debugger
if (e.keyCode == 116) {
validNavigation = true;
}
});


// Attach the event click for all links in the page
$("a").bind("click", function () {
debugger
validNavigation = true;
});


// Attach the event submit for all forms in the page
$("form").bind("submit", function () {
debugger
validNavigation = true;
});


// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function () {
debugger
validNavigation = true;
});


}`enter code here`