如何捕获浏览器窗口关闭事件?
Posted
技术标签:
【中文标题】如何捕获浏览器窗口关闭事件?【英文标题】:How to capture the browser window close event? 【发布时间】:2010-12-10 13:23:19 【问题描述】:我想捕获浏览器窗口/标签关闭事件。 我用 jQuery 尝试了以下操作:
jQuery(window).bind(
"beforeunload",
function()
return confirm("Do you really want to close?")
)
但它也适用于表单提交,这不是我想要的。我想要一个仅在用户关闭窗口时触发的事件。
【问题讨论】:
【参考方案1】:每当用户出于任何原因离开您的页面时,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
事件,因此如果您添加新表单,您还需要将处理程序绑定到它。
请注意,如果不同的事件处理程序取消提交或导航,如果窗口稍后实际关闭,您将丢失确认提示。您可以通过记录submit
和click
事件中的时间并检查beforeunload
是否在几秒钟后发生来解决此问题。
【讨论】:
是的,工作得很好!较新版本的 jquery 支持 $('form').live('submit, function() ). 您的解决方案很好,但在刷新的情况下如何取消活动?我只在浏览器关闭时才想要事件,没有刷新的情况 浏览器似乎将 beforeunload 的返回值显示为确认对话框。所以我认为这个答案更准确:link 这是否会使用Ctrl + r
、F5
、Ctrl + Shift + r
处理页面刷新并更改浏览器 URL?
@Jonny:现在只是.on()
。【参考方案2】:
也许只是在表单的submit
事件处理程序中取消绑定beforeunload
事件处理程序:
jQuery('form').submit(function()
jQuery(window).unbind("beforeunload");
...
);
【讨论】:
通过在表单标签定义中指定 this 不使用 jQuery 不是很简单吗? : ` @awe 但是您需要在每个表单中包含onsubmit=...
。 (我在某个 webapp 中每页有很多表单)【参考方案3】:
对于跨浏览器解决方案(在 Chrome 21、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 开始,消息“您真的要关闭吗?”不显示。 FF 只显示一条通用消息。见https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload中的注释
【讨论】:
这个可以在浏览器中始终如一地工作。只是一个简短的说明;我将live
和bind
语句都更新为on
,这与最新级别的jQuery 配合得很好。谢谢!【参考方案4】:
window.onbeforeunload = function ()
return "Do you really want to close?";
;
【讨论】:
【参考方案5】:我的回答旨在提供简单的基准。
如何
见@SLaks answer。
$(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: ∞(或双击)Explorer 11:0 秒。Safari: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.
【讨论】:
【参考方案6】:对于与 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;
);
【讨论】:
这个答案是正确的,但是对于那些在刷新浏览器时遇到此事件发生问题的人,请将 if 更改为以下代码: if (inFormOrLink !== undefined && !inFormOrLink)【参考方案7】:我使用了 Slaks 的答案,但没有按原样工作,因为 onbeforeunload returnValue 被解析为字符串,然后显示在浏览器的确认框中。所以值 true 被显示出来,比如“true”。
只使用 return 工作。 这是我的代码
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;
)
【讨论】:
【参考方案8】:也许您可以处理 OnSubmit 并设置一个标志,以便稍后在 OnBeforeUnload 处理程序中检查。
【讨论】:
【参考方案9】:jQuery(window).bind(
"beforeunload",
function (e)
var activeElementTagName = e.target.activeElement.tagName;
if (activeElementTagName != "A" && activeElementTagName != "INPUT")
return "Do you really want to close?";
)
【讨论】:
【参考方案10】:不幸的是,无论是重新加载、新页面重定向还是浏览器关闭都会触发该事件。另一种方法是捕获触发事件的 id,如果它是表单,则不触发任何功能,如果它不是表单的 id,则在页面关闭时执行您想要执行的操作。我不确定这是否也可以直接实现并且很乏味。
您可以在客户关闭标签之前做一些小事。 javascript detect browser close tab/close browser 但是如果您的操作列表很大并且选项卡在完成之前关闭,您将无能为力。你可以试试,但根据我的经验,不要依赖它。
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
【讨论】:
【参考方案11】:如果您的表单提交将它们带到另一个页面(正如我假设的那样,因此触发了beforeunload
),您可以尝试将您的表单提交更改为 ajax 调用。这样,他们在提交表单时就不会离开您的页面,您可以随意使用beforeunload
绑定代码。
【讨论】:
【参考方案12】:从 jQuery 1.7 开始,不推荐使用 .live() 方法。使用 .on() 附加事件处理程序。旧版本 jQuery 的用户应该使用 .delegate() 而不是 .live()
$(window).bind("beforeunload", function()
return true || confirm("Do you really want to close?");
);
完成或链接
$(window).unbind();
【讨论】:
【参考方案13】:也试试这个
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
;
【讨论】:
【参考方案14】:我的问题:“onbeforeunload”事件只有在提交(点击)次数为奇数时才会触发。我在 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');
【讨论】:
【参考方案15】:只需验证...
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.close === false;【参考方案16】: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`
【讨论】:
【参考方案17】:以下对我有用;
$(window).unload(function(event)
if(event.clientY < 0)
//do whatever you want when closing the window..
);
【讨论】:
如果您单击浏览器关闭按钮或选项卡关闭按钮,event.clientY
是否定的。但是,当您使用键盘快捷键(F5、Ctrl-R)重新加载页面或使用键盘快捷键(例如 Alt-F4)关闭浏览器时,此值为正。因此,您不能依靠事件位置来区分浏览器关闭事件和页面重新加载事件。以上是关于如何捕获浏览器窗口关闭事件?的主要内容,如果未能解决你的问题,请参考以下文章