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


149

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

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

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

Answers:


211

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几秒钟后发生,来解决此问题。


8
是的,工作很棒!较新版本的jquery支持$('form')。live('submit,function(){})。
Venkat D.

4
您的解决方案很好,但是在刷新的情况下如何取消事件?我仅在关闭浏览器后才需要事件,没有刷新的情况
Refael

似乎浏览器将beforeunload的返回值显示为确认对话框。因此,我认为这个答案更为准确:链接
tahagh 2014年

2
做一个页面的这个手柄刷新使用Ctrl + rF5Ctrl + Shift + r和更改浏览器的网址?
Arti 2015年

1
@Jonny:现在只是.on()
SLaks '17

45

也许只是将beforeunload事件处理程序绑定到表单的submit事件处理程序中:

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

3
通过在表单标签定义中指定不使用jQuery,这不是一样容易吗?:`<形式的onsubmit = “window.onbeforeunload = NULL;”>
畏惧

4
@awe但是您需要onsubmit=...在每种形式中都包含它。(在某个webapp中,每页有很多表格)
KajMagnus 2011年

16

对于跨浏览器解决方案(已在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/zh-CN/docs/DOM/window.onbeforeunload中的注释


3
这一程序在所有浏览器中都能一致地工作。只是一个简短的笔记;我将livebind语句都更新为on,与最新版本的jQuery一起使用效果很好。谢谢!
Sablefoste


4

对于与出于各种原因而使用Anchor标记的第三方控件(例如Telerik(例如:RadComboBox)和DevExpress)兼容的解决方案,请考虑使用以下代码,它是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;
});

1
这个答案是正确的,但是对于那些刷新浏览器时发生此事件的人,请将if更改为以下代码:if(inFormOrLink!== undefined &&!inFormOrLink)
LeonPierre 2015年

4

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

如何

参见@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?),它将等待用户的响应。

镀铬:2秒。
Firefox:∞(或双击,或强制关闭)
边缘:∞(或双击)
Explorer 11:0秒。
Safari待办事项

我们用来测试的是:

  • 带有请求日志的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.

3

我使用了Slaks答案,但是它没有按原样工作,因为onbeforeunload returnValue被解析为字符串,然后显示在浏览器的确认框中。因此显示的值为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;
})

1

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


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

1

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

您可以在客户关闭标签页之前做一些小事情。javascript检测浏览器的“关闭”选项卡/“关闭”浏览器,但是如果您的操作列表很大,并且该选项卡在完成之前关闭,您将无能为力。您可以尝试一下,但根据我的经验,请不要依赖它。

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/zh-CN/docs/Web/Reference/Events/beforeunload?redirectlocale=zh-CN&redirectslug=DOM/Mozilla_event_reference/beforeunload


0

如果您的表单提交将它们带到另一个页面(我认为是这样,因此触发beforeunload),则可以尝试将表单提交更改为ajax调用。这样,他们提交表单时他们就不会离开您的页面,您可以根据需要使用beforeunload绑定代码。


0

我的问题:只有在提交(点击)次数奇数的情况下,才会触发“ 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');   
}

0

从jQuery 1.7开始,不推荐使用.live()方法。使用.on()附加事件处理程序。较旧版本的jQuery的用户应优先使用.delegate()而不是.live()

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

完成或链接

$(window).unbind();

0

也尝试一下

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

-1

只要验证一下...

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.closed === false;
Sergey P.又名天青,

-1
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`

-7

跟随对我有用;

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

这是一个jQuery函数。
maxisam 2012年

7
event.clientY如果单击浏览器关闭按钮或选项卡关闭按钮,则为负。但是,当您使用键盘快捷键(F5,Ctrl-R)重新加载页面或使用键盘快捷键(例如Alt-F4)关闭浏览器时,此值为正。因此,您不能依靠事件位置来区分浏览器关闭事件和页面重新加载事件。
朱利安·克朗格
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.