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

我想要捕获浏览器窗口/选项卡closures事件。 我已经使用jQuery尝试了以下内容:

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

但它也可以用于表单提交,这不是我想要的。 我想要一个事件,只有当用户closures窗口触发。

每当用户因任何原因离开您的页面时,都会触发beforeunload事件。

例如,如果用户提交表单,单击链接,closures窗口(或选项卡)或使用地址栏,search框或书签转到新页面,则会被触发。

您可以使用以下代码排除表单提交和超链接(除了其他框架):

 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事件一起工作,所以如果你添加一个新的表单,你也需要绑定这个处理器。

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

也许只是在表单的submit事件处理程序中取消绑定beforeunload事件处理程序:

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

对于跨浏览器的解决scheme(在Chrome 21,IE9,FF15中testing),请考虑使用以下代码,这是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以来,消息“你真的想closures吗? 不显示。 FF只是显示一个通用的消息。 请参阅https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload中的说明;

 window.onbeforeunload = function () { return "Do you really want to close?"; }; 

对于像Telerik(例如:RadComboBox)和DevExpress这样的使用Anchor标签的第三方控件在各种原因下运行良好的解决scheme,请考虑使用下面的代码,这是一个稍微调整过的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; }); 

我用Slaks的答案,但是这是不工作的,因为onbeforeunload returnValue被parsing为一个string,然后显示在浏览器的确认框。 所以显示的值为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; }) 

也许你可以处理OnSubmit并设置一个标志,你稍后检查你的OnBeforeUnload处理程序。

 jQuery(window).bind( "beforeunload", function (e) { var activeElementTagName = e.target.activeElement.tagName; if (activeElementTagName != "A" && activeElementTagName != "INPUT") { return "Do you really want to close?"; } }) 

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

如何

请参阅@SLaks答案 。

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

浏览器需要多长时间才能closures页面?

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

Chrome :2秒。
Firefox :∞(或双击,或强行closures)
边缘 :∞(或双击)
资源pipe理器11 :0秒。
SafariTODO

我们用什么来testing这个:

  • 具有请求日志的Node.js Express服务器
  • 以下简短的HTML文件

它的function是在浏览器closures页面(同步)之前发送尽可能多的请求。

 <html> <body> <script src="jquery-3.1.1.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. 

如果你的表单提交把他们带到另一个页面(因为我认为它做了,因此触发beforeunload ),你可以尝试改变你的表单提交ajax调用。 这样,他们不会离开你的页面,当他们提交表单,你可以使用你的beforeunload绑定代码,如你所愿。

我的问题:“onbeforeunload”事件只有在发生奇数次提交(点击)时才会触发。 我有类似的线程在SO的解决scheme的组合,让我的解决scheme工作。 以及我的代码会说话。

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

从jQuery 1.7开始,.live()方法已被弃用。 使用.on()附加事件处理程序。 老版本的jQuery用户应该优先使用.delegate().live()

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

在完成或链接

 $(window).unbind(); 

只要validation…

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

不幸的是,无论是重新加载,新页面redirect还是浏览器closures事件都将被触发。 另一种方法是捕捉触发事件的id,如果是form,则不会触发任何函数,如果不是表单的id,则在页面closures时执行您想要执行的操作。 我不确定这是否也是可能的,而且是单调乏味的。

客户closures标签之前,您可以做一些小事情。 JavaScript检测浏览器closures选项卡/closures浏览器,但如果您的动作列表很大,选项卡closures之前,它是无奈的。 你可以尝试,但以我的经验不依赖于它。

 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

试试这也

 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` 

以下为我工作;

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