【问题标题】:How to capture the browser window close event?如何捕获浏览器窗口关闭事件?
【发布时间】:2023-03-29 08:34:01
【问题描述】:

我想捕获浏览器窗口/标签关闭事件。 我用 jQuery 尝试了以下操作:

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

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

【问题讨论】:

    标签: javascript jquery events browser


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 通过在表单标签定义中指定 this 不使用 jQuery 不是很简单吗? : `
      • @awe 但是您需要在每个表单中包含 onsubmit=...。 (我在某个 webapp 中每页有很多表单)
      【解决方案3】:

      每当用户出于任何原因离开您的页面时,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 是否在几秒钟后发生来解决此问题。

      【讨论】:

      • 是的,工作得很好!较新版本的 jquery 支持 $('form').live('submit, function() { }).
      • 您的解决方案很好,但在刷新的情况下如何取消活动?我只在浏览器关闭时才想要事件,没有刷新的情况
      • 浏览器似乎将 beforeunload 的返回值显示为确认对话框。所以我认为这个答案更准确:link
      • 这是否会使用Ctrl + rF5Ctrl + Shift + r 处理页面刷新并更改浏览器 URL?
      • @Jonny:现在只是.on()
      【解决方案4】:

      如果您的表单提交将它们带到另一个页面(正如我假设的那样,因此触发了beforeunload),您可以尝试将您的表单提交更改为 ajax 调用。这样,他们在提交表单时就不会离开您的页面,您可以随意使用您的beforeunload 绑定代码。

      【讨论】:

        【解决方案5】:

        以下对我有用;

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

        【讨论】:

        • 如果您单击浏览器关闭按钮或选项卡关闭按钮,event.clientY 是否定的。但是,当您使用键盘快捷键(F5、Ctrl-R)重新加载页面或使用键盘快捷键(例如 Alt-F4)关闭浏览器时,此值为正值。因此,您不能依靠事件位置来区分浏览器关闭事件和页面重新加载事件。
        【解决方案6】:

        我的问题:“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'); 
        }
        

        【讨论】:

          【解决方案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】:

            对于跨浏览器解决方案(在 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中的注释

            【讨论】:

            • 这个可以在浏览器中始终如一地工作。只是一个简短的说明;我将livebind 语句都更新为on,这与最新级别的jQuery 配合得很好。谢谢!
            【解决方案9】:

            对于与 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)
            【解决方案10】:

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

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

            完成或链接

            $(window).unbind();
            

            【讨论】:

              【解决方案11】:

              只需验证...

              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;
              【解决方案12】:
              window.onbeforeunload = function () {
                  return "Do you really want to close?";
              };
              

              【讨论】:

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

                【讨论】:

                  【解决方案14】:

                  不幸的是,无论是重新加载、新页面重定向还是浏览器关闭都会触发该事件。另一种方法是捕获触发事件的 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

                  【讨论】:

                    【解决方案15】:

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

                    如何

                    @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 秒。
                    SafariTODO

                    我们用来测试的:

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

                    【讨论】:

                      【解决方案16】:

                      也试试这个

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

                      【讨论】:

                        【解决方案17】:
                        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`
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2011-10-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2010-11-04
                          • 2010-11-25
                          相关资源
                          最近更新 更多