【问题标题】:Run JavaScript code on window close or page refresh?在窗口关闭或页面刷新时运行 JavaScript 代码?
【发布时间】:2021-04-22 04:29:51
【问题描述】:

当用户关闭浏览器窗口或刷新页面时,有没有办法运行最终的 JavaScript 代码?

我正在考虑类似于 onload 但更像 onclose 的东西?谢谢。

我不喜欢 onbeforeunload 方法,它总是会弹出一个确认框(离开页面/留在 mozilla 上)或(重新加载/不要在 chrome 上重新加载)。有没有办法安静地执行代码?

【问题讨论】:

标签: javascript browser


【解决方案1】:

有没有办法安静地执行代码? (没有弹出窗口)

我已成功使用此方法,但其他方法(例如返回 null 或 false)存在问题。在 ie、Edge、Chrome、Opera 上测试。

window.addEventListener('beforeunload', function (e) {
  // the absence of a returnValue property on the event will guarantee the browser unload happens
  delete e['returnValue'];
  // my code that silently runs goes here
});

以上代码直接从Mozilla.org's onbeforeunload doc粘贴​​p>

更新:这似乎不适用于 IOS Safari :( 所以不是一个完整的解决方案,但也许它仍然可以帮助某人。

【讨论】:

    【解决方案2】:

    window.onbeforeunloadwindow.onunload 都有,它们的使用方式因浏览器而异。您可以通过将窗口属性设置为函数或使用.addEventListener 来分配它们:

    window.onbeforeunload = function(){
       // Do something
    }
    // OR
    window.addEventListener("beforeunload", function(e){
       // Do something
    }, false);
       
    

    通常,如果您需要阻止用户离开页面,则使用onbeforeunload(例如,用户正在处理一些未保存的数据,因此他/她应该在离开前保存)。据我所知,Opera 不支持onunload,但您始终可以同时设置两者。

    【讨论】:

    • 这对我有用:Firefox (69.0.2) 和 Chrome (77.0.3865.90)
    • 我知道这是一个可接受的答案,但是当我在 //DO SOMETHING 中添加警报时,它不会发送警报消息。这是正常的吗?因为我觉得它在我关闭或刷新时都没有发出警报。
    【解决方案3】:

    好的,我找到了一个可行的解决方案,它包括使用beforeunload 事件,然后让处理程序返回null。这将执行所需的代码,而不会弹出确认框。它是这样的:

    window.onbeforeunload = closingCode;
    function closingCode(){
       // do something...
       return null;
    }
    

    【讨论】:

    • 这不是在导航出去和刷新 (F5) 时也触发吗?如果是这样,它并没有真正解决问题......
    • 未测试,但我认为return false; 的作用相同(即阻止默认行为)并且在语义上更正确。
    • return false 仍然会弹出对话框询问您是否要离开页面。我在锚上进行了测试。使用 return null 对话框没有弹出,但它仍然是 console.log
    【解决方案4】:

    有时您可能希望让服务器知道用户正在离开页面。这很有用,例如,清理临时存储在服务器上的未保存图像、将该用户标记为“离线”或在他们完成会话时进行记录。

    过去,您会在beforeunload 函数中发送AJAX 请求,但这有两个问题。如果您发送异步请求,则无法保证该请求会正确执行。如果您发送同步请求,它更可靠,但浏览器会挂起,直到请求完成。如果这是一个缓慢的请求,这会给用户带来极大的不便。

    后来navigator.sendBeacon()。通过使用sendBeacon() 方法,数据在用户代理有机会时异步传输到Web 服务器,不会延迟卸载或影响下一次导航的性能。这解决了提交分析数据的所有问题:数据发送可靠,异步发送,并且不影响下一页的加载。

    除非您只针对桌面用户,否则sendBeacon() should not be used with unload or beforeunload 因为这些在移动设备上并不可靠。相反,您可以收听visibilitychange 事件。每当您的页面可见并且用户切换选项卡、切换应用程序、转到主屏幕、接听电话、离开页面、关闭选项卡、刷新等时,都会触发此事件。

    下面是它的用法示例:

    document.addEventListener('visibilitychange', function() {
        if (document.visibilityState == 'hidden') { 
            navigator.sendBeacon("/log.php", analyticsData);
        }
    });
    

    当用户返回页面时,document.visibilityState 将变为'visible',因此您也可以处理该事件。

    sendBeacon()supported 在:

    • 边缘 14
    • 火狐31
    • 铬 39
    • Safari 11.1
    • 歌剧 26
    • iOS Safari 11.4

    目前不支持:

    • Internet Explorer
    • 迷你歌剧

    这里是polyfill for sendBeacon(),以防您需要添加对不受支持的浏览器的支持。如果该方法在浏览器中不可用,它将发送一个同步的 AJAX 请求。

    更新:

    值得一提的是sendBeacon() 只发送POST 请求。如果您需要使用任何其他方法发送请求,另一种方法是使用fetch API 并将keepalive 标志设置为true,这使其行为方式与sendBeacon() 相同。 Browser support for the fetch API 差不多。

    fetch(url, {
       method: ..., 
       body: ...,            
       headers: ...,       
       credentials: 'include',
       mode: 'no-cors',
       keepalive: true,
    })
    

    【讨论】:

    • 这个问题属于“向服务器发送请求”案例的范围。这个想法是能够在每个用户打开的标签上保留标签,并在标签关闭时在后端进行清理。
    • @Peter 为了完整起见,我将其包括在内,但我删除了它。
    • @Mike,请不要删除您的答案。它不仅完成了选定的最佳答案(它应该是你的),而且还呈现用于捕获窗口退出或关闭的事件
    • @AshokKumar 您可以控制发送到服务器的内容。如果您想通过 GET 发送内容,没有什么可以阻止您将请求发送到 http://example.com/script.php?token=something&var1=val1&var2=val2 之类的东西,从而将这些值放入 GET。
    • @cYrus,很好。在发布我的答案时,MDN recommended using unload,但他们已经改变了立场。我已经相应地更新了我的答案。
    【解决方案5】:

    jQuery 版本:

    $(window).unload(function(){
        // Do Something
    });
    

    更新:jQuery 3:

    $(window).on("unload", function(e) {
        // Do Something
    });
    

    感谢加勒特

    【讨论】:

      【解决方案6】:

      此处的文档鼓励监听 onbeforeunload 事件和/或在窗口上添加事件监听器。

      window.addEventListener('beforeunload', function(event) {
        //do something here
      }, false);
      

      您也可以使用函数或函数引用填充窗口的 .onunload 或 .onbeforeunload 属性。

      虽然跨浏览器的行为没有标准化,但该函数可能会返回一个值,浏览器在确认是否离开页面时将显示该值。

      【讨论】:

        【解决方案7】:

        您可以使用window.onbeforeunload

        window.onbeforeunload = confirmExit;
        function confirmExit(){
            alert("confirm exit is being called");
            return false;
        }
        

        【讨论】:

          【解决方案8】:

          该事件称为beforeunload,因此您可以将函数分配给window.onbeforeunload

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-12-19
            • 1970-01-01
            • 1970-01-01
            • 2014-09-01
            • 1970-01-01
            相关资源
            最近更新 更多