前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >注意,这个 JavaScript 事件即将弃用!

注意,这个 JavaScript 事件即将弃用!

作者头像
ConardLi
发布2023-08-23 13:40:06
2800
发布2023-08-23 13:40:06
举报
文章被收录于专栏:code秘密花园code秘密花园

简单的说:从 Chrome 117 开始,unload 事件将逐渐弃用。

通常情况,在 HTML 文档即将被卸载时,unload 事件将会调用。理论上,它可用来在用户离开页面时运行一些代码,或者作为会话回调结束时运行代码。

代码语言:javascript
复制
<!doctype html>
<html>
  <head>
    <title>Parent Frame</title>
    <script>
      window.addEventListener("beforeunload", function (event) {
        console.log("即将卸载");
      });
      window.addEventListener("unload", function (event) {
        console.log("卸载");
      });
    </script>
  </head>
  <body>
      ConardLi ...
  </body>
</html>

一般我们会用于以下场景:

  • 保存用户数据:离开页面前保存数据;
  • 执行清理任务:在离开页面之前关闭打开的资源;
  • 发送分析:在离开页面时发送与用户交互相关的数据。

为啥要弃用

这个 unload 事件非常不可靠。在很多浏览器中代码都不会按照预期运行。

另外,因为它是早于 bfcache (浏览器的前进,后退,缓存操作)的,所以会对正常的 bfcache 进行阻塞,对网站的性能产生负面影响(正常根据规范来讲,unload 是不应该阻止用户的 bfcache 操作的)。这算是一个历史遗留问题,其实 Safari 也早就对它进行了弃用。

有什么替代方案

第一个替代方式就是 visibilitychange ,当用户切换选项卡、最小化浏览器窗口或打开新页面时,都会触发这个事件。当我们需要在页面不可见是做点操作时,可以判断这个 document.visibilityState 是否为 hidden

代码语言:javascript
复制
document.addEventListener('visibilitychange', function() {
  if (document.visibilityState === 'visible') {
    // 页面变为可见状态时的操作
    console.log('页面可见');
  } else if (document.visibilityState === 'hidden') {
    // 页面变为不可见状态时的操作
    console.log('页面不可见');
  }
});

第二个替代事件为 pagehide ,它会在用户点击跳转其他链接、前进或后退按钮,或关闭浏览器选项卡时触发,也能够用来确定用户什么时候离开界面:

代码语言:javascript
复制
window.addEventListener('pagehide', function(event) {
  console.log('页面即将隐藏或关闭');
  // 执行相应的操作
});

pagehide 不会像 unload 一样让页面不符合bfcache (浏览器的前进,后退,缓存操作)的条件。

怎么检测

Lighthouse 有一项专门的 no-unload-listeners 检测,如果页面上的任何 JavaScript(包括来自第三方库的 JavaScript)添加了unload 事件侦听器,就会发出警告。

另外 Chrome DevTools 也有一个 back-foward-cache 检测,可帮助我们识别可能阻止页面有后退/前进缓存资格的问题,这里面就包括使用 unload 事件。

使用 Permissions-Policy 禁用

如果你知道自己的网站有用到这个事件,但是又不知道怎么移除,可以使用 Permissions-Policy 来进行限制,Chrome 115 版本专门增加了对 unload 的配置:

递归地禁用当前页面及其所有子 iframeunload事件,可以添加如下 Header

代码语言:javascript
复制
Permissions-Policy: unload=()

递归地禁用当前页面及其所有子 iframeunload事件,但是想保留部分页面的:

代码语言:javascript
复制
Permissions-Policy: unload=(https://www.conardli.com)

只是上知道网站上是否有调用 unload 事件,但不进行拦截:

代码语言:javascript
复制
Permissions-Policy-Report-Only: unload=()

最后

参考:

  • https://developer.chrome.com/en/blog/deprecating-unload/
  • https://developer.mozilla.org/docs/Web/API/Window/unload_event
  • https://developer.chrome.com/blog/page-lifecycle-api/#the-unload-event
  • https://web.dev/bfcache/#never-use-the-unload-event
  • https://developer.chrome.com/blog/page-lifecycle-api/#event-visibilitychange
  • https://developer.chrome.com/blog/page-lifecycle-api/#event-pagehide
  • https://developer.chrome.com/docs/lighthouse/
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 code秘密花园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为啥要弃用
  • 有什么替代方案
  • 怎么检测
  • 使用 Permissions-Policy 禁用
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档