简体   繁体   English

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

[英]How to capture the browser window close event?

I want to capture the browser window/tab close event.我想捕获浏览器窗口/选项卡关闭事件。 I have tried the following with jQuery:我用 jQuery 尝试了以下操作:

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

But it works on form submission as well, which is not what I want.但它也适用于表单提交,这不是我想要的。 I want an event that triggers only when the user closes the window.我想要一个仅在用户关闭窗口时触发的事件。

The beforeunload event fires whenever the user leaves your page for any reason.每当用户出于任何原因离开您的页面时,都会触发beforeunload事件。

For example, it will be fired if the user submits a form, clicks a link, closes the window (or tab), or goes to a new page using the address bar, search box, or a bookmark.例如,如果用户提交表单、单击链接、关闭窗口(或选项卡)或使用地址栏、搜索框或书签进入新页面,它将被触发。

You could exclude form submissions and hyperlinks (except from other frames) with the following code:您可以使用以下代码排除表单提交和超链接(其他框架除外):

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

For jQuery versions older than 1.7, try this:对于早于 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; 
})

The live method doesn't work with the submit event, so if you add a new form, you'll need to bind the handler to it as well. live方法不适用于submit事件,因此如果您添加一个新表单,您还需要将处理程序绑定到它。

Note that if a different event handler cancels the submit or navigation, you will lose the confirmation prompt if the window is actually closed later.请注意,如果不同的事件处理程序取消提交或导航,如果窗口稍后实际关闭,您将失去确认提示。 You could fix that by recording the time in the submit and click events, and checking if the beforeunload happens more than a couple of seconds later.您可以通过在submitclick事件中记录时间来解决这个问题,并检查beforeunload是否在几秒钟后发生。

Maybe just unbind the beforeunload event handler within the form's submit event handler:也许只是在表单的submit事件处理程序中解除绑定beforeunload事件处理程序:

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

For a cross-browser solution (tested in Chrome 21, IE9, FF15), consider using the following code, which is a slightly tweaked version of Slaks' code:对于跨浏览器解决方案(在 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;
}); 

Note that since Firefox 4, the message "Do you really want to close?"请注意,从 Firefox 4 开始,消息“您真的要关闭吗?” is not displayed.不显示。 FF just displays a generic message. FF 仅显示一般消息。 See note in https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload请参阅https://developer.mozilla.org/en-US/docs/DOM/window.onbeforeunload 中的注释

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

My answer is aimed at providing simple benchmarks.我的回答旨在提供简单的基准。

HOW TO如何

See @SLaks answer .请参阅@SLaks 答案

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

How long does the browser take to finally shut your page down?浏览器需要多长时间才能最终关闭您的页面?

Whenever an user closes the page ( x button or CTRL + W ), the browser executes the given beforeunload code, but not indefinitely.每当用户关闭页面( x按钮或CTRL + W )时,浏览器都会执行给定的beforeunload代码,但不会无限期地执行。 The only exception is the confirmation box ( return 'Do you really want to close? ) which will wait until for the user's response.唯一的例外是确认框( return 'Do you really want to close? ),它将等待用户的响应。

Chrome : 2 seconds.:2 秒。
Firefox : ∞ (or double click, or force on close) Firefox :∞(或双击,或强制关闭)
Edge : ∞ (or double click)边缘:∞(或双击)
Explorer 11 : 0 seconds.探险家 11 :0 秒。
Safari : TODO Safari :待办事项

What we used to test this out:我们用来测试的内容:

  • A Node.js Express server with requests log带有请求日志的 Node.js Express 服务器
  • The following short HTML file以下简短的 HTML 文件

What it does is to send as many requests as it can before the browser shut downs its page (synchronously).它所做的是在浏览器关闭其页面(同步)之前发送尽可能多的请求。

<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 output:铬输出:

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.

For a solution that worked well with third party controls like Telerik (ex.: RadComboBox) and DevExpress that use the Anchor tags for various reasons, consider using the following code, which is a slightly tweaked version of desm's code with a better selector for self targeting anchor tags:对于与 Telerik(例如:RadComboBox)和 DevExpress 等出于各种原因使用 Anchor 标签的第三方控件配合良好的解决方案,请考虑使用以下代码,这是 desm 代码的略微调整版本,具有更好的 self 选择器定位锚标签:

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

I used Slaks answer but that wasn't working as is, since the onbeforeunload returnValue is parsed as a string and then displayed in the confirmations box of the browser.我使用了 Slaks 答案,但这并没有按原样工作,因为 onbeforeunload returnValue 被解析为一个字符串,然后显示在浏览器的确认框中。 So the value true was displayed, like "true".所以显示了 true 值,比如“true”。

Just using return worked.只是使用返回工作。 Here is my code这是我的代码

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

Unfortunately, whether it is a reload, new page redirect, or browser close the event will be triggered.不幸的是,无论是重新加载、新页面重定向还是浏览器关闭都会触发该事件。 An alternative is catch the id triggering the event and if it is form dont trigger any function and if it is not the id of the form then do what you want to do when the page closes.另一种方法是捕获触发事件的 id,如果它是表单,则不触发任何功能,如果它不是表单的 id,则在页面关闭时执行您想做的操作。 I am not sure if that is also possible directly and is tedious.我不确定这是否也可以直接实现并且很乏味。

You can do some small things before the customer closes the tab.您可以在客户关闭选项卡之前做一些小事。 javascript detect browser close tab/close browser but if your list of actions are big and the tab closes before it is finished you are helpless. javascript 检测浏览器关闭选项卡/关闭浏览器,但如果您的操作列表很大并且选项卡在完成之前关闭,您将无能为力。 You can try it but with my experience donot depend on it.你可以试试,但根据我的经验,不要依赖它。

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 https://developer.mozilla.org/en-US/docs/Web/Reference/Events/beforeunload?redirectlocale=en-US&redirectslug=DOM/Mozilla_event_reference/beforeunload

My Issue: The 'onbeforeunload' event would only be triggered if there were odd number of submits(clicks).我的问题:只有在提交(点击)次数为奇数时才会触发“onbeforeunload”事件。 I had a combination of solutions from similar threads in SO to have my solution work.我在 SO 中使用了来自类似线程的解决方案的组合来使我的解决方案起作用。 well my code will speak.好吧,我的代码会说话。

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

If your form submission takes them to another page (as I assume it does, hence the triggering of beforeunload ), you could try to change your form submission to an ajax call.如果您的表单提交将它们带到另一个页面(正如我假设的那样,因此触发beforeunload ),您可以尝试将表单提交更改为 ajax 调用。 This way, they won't leave your page when they submit the form and you can use your beforeunload binding code as you wish.这样,他们在提交表单时就不会离开您的页面,您可以根据需要使用beforeunload绑定代码。

As of jQuery 1.7, the .live() method is deprecated.从 jQuery 1.7 开始,不推荐使用 .live() 方法。 Use .on() to attach event handlers.使用 .on() 附加事件处理程序。 Users of older versions of jQuery should use .delegate() in preference to .live()旧版本 jQuery 的用户应该优先使用 .delegate() 而不是 .live()

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

on complete or link在完整或链接上

$(window).unbind();

Try this also也试试这个

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

Just verify...只要验证...

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

Following worked for me;以下为我工作;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM