如何捕获浏览器窗口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,您将会失去确认提示。 您可以通过在submit
和click
事件中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秒。
Safari : TODO
我们用什么来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 });
试试这也
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.. } });