beforeunload事件
当浏览器窗口关闭或者刷新时,会触发beforeunload事件。当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。
HTML规范指出作者应该使用 Event.preventDefault()
而非 Event.returnValue
,然而,不是所有浏览器都支持这么做。
window.onbeforeunload = function (e) {
e = e || window.event;
// 兼容IE8和Firefox 4之前的版本
if (e) {
e.returnValue = '';
}
// Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
return '';
};
注意:提示词无法生效;用户操作了页面(比如点击了页面)浏览器认为页面内容发生了变化,监听到该事件时才会有弹窗提示。
某些浏览器过去在确认对话框中显示返回的字符串,从而使事件处理程序能够向用户显示自定义消息。但是,此方法已被弃用,并且在大多数浏览器中不再支持。
为避免意外弹出窗口,除非页面已与之交互,否则浏览器可能不会显示在beforeunload
事件中创建的提示,甚至根本不会显示它们。
unload事件
该事件在关闭窗口资源和内容的时候触发。页面资源的清除工作会在 unload
事件之后进行。
通常而言,我们推荐使用 window.addEventListener()
来监听 unload
事件,而不是直接给 onunload
赋值。
window.addEventListener("unload", function(event) { ... });
window.onunload = function(event) { ... };
onunload
特性(乃至 unload
事件本身) 并非使用 sendBeacon()
的正确途径,要调用 sendBeacon()
接口,应当使用 visibilitychange
和 pagehide
事件。 参见 Beacon API is broken。
注意: 由于浏览器设置不同,此事件可能无法按预期工作。
Navigator.sendBeacon()
navigator.sendBeacon()
方法可用于页面卸载时,少量数据异步传输到Web服务器。
navigator.sendBeacon(url, data);
当用户代理成功把数据加入传输队列时,sendBeacon()
方法将会返回 true
,否则返回 false
。
描述
这个方法主要用于满足统计和诊断代码的需要,这些代码通常尝试在卸载(unload)文档之前向web服务器发送数据。过早的发送数据可能导致错过收集数据的机会。然而,对于开发者来说保证在文档卸载期间发送数据一直是一个困难。因为用户代理通常会忽略在 unload
事件处理器中产生的异步 XMLHttpRequest
。
为了解决这个问题, 统计和诊断代码通常要在 unload
或者 beforeunload
事件处理器中发起一个同步 XMLHttpRequest
来发送数据。同步的 XMLHttpRequest
迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。下一个页面对于这种较差的载入表现无能为力。
有一些技术被用来保证数据的发送。其中一种是通过在卸载事件处理器中创建一个图片元素并设置它的 src 属性的方法来延迟卸载以保证数据的发送。因为绝大多数用户代理会延迟卸载以保证图片的载入,所以数据可以在卸载事件中发送。另一种技术是通过创建一个几秒钟的 no-op 循环来延迟卸载并向服务器发送数据。
这些技术不仅编码模式不好,其中的一些甚至并不可靠而且会导致非常差的页面载入性能。
下面的例子展示了一个理论上的统计代码——在卸载事件处理器中尝试通过一个同步的 XMLHttpRequest
向服务器发送数据。这导致了页面卸载被延迟。
window.addEventListener('unload', logData, false);
function logData() {
var client = new XMLHttpRequest();
client.open("POST", "/log", false); // 第三个参数表明是同步的 xhr
client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
client.send(analyticsData);
}
下面的例子展示了一个理论上的统计代码模式——通过使用 sendBeacon()
方法向服务器发送数据。
window.addEventListener('unload', logData, false);
function logData() {
navigator.sendBeacon("/log", analyticsData);
}
参看文章:
https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/sendBeacon
Navigator.sendBeacon 无阻塞发送统计数据