Document:visibilitychange 事件

452 阅读2分钟

当其选项卡的内容变得可见或被隐藏时,会在 document 上触发 visibilitychange 事件。

该事件不可取消。

语法

在像 addEventListener() 的方法中使用事件名称,或设置事件处理器属性。

addEventListener("visibilitychange", (event) => {});

onvisibilitychange = (event) => {};

使用说明

该事件不包括文档的更新的可见性状态,但是你可以从文档的 visibilityState 属性中获取该信息。

当用户导航到新页面、切换标签页、关闭标签页、最小化或关闭浏览器,或者在移动设备上从浏览器切换到不同的应用程序时,该事件就会触发,其 visibilityState 为 hidden。过渡到 hidden 是页面能可靠观察到的最后一个事件,因此开发人员应将其视为用户会话的可能结束(例如,用于[发送分析数据])。

向 hidden 过渡也是页面停止用户界面更新和停止用户不想在后台运行的任何任务的好时机。

示例

本示例在文档可见时开始播放音乐曲目,在文档不再可见时暂停音乐。

document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "visible") {
    backgroundMusic.play();
  } else {
    backgroundMusic.pause();
  }
});

在文档转向隐藏状态时发送会话结束分析报告

本示例将 hidden 转换视为用户会话的结束,并使用 Navigator.sendBeacon() API 发送相应的分析结果。

document.onvisibilitychange = () => {
  if (document.visibilityState === "hidden") {
    navigator.sendBeacon("/log", analyticsData);
  }
};

备注

document.visibilityState 过渡到 hidden 时,页面中的定时器(如 setTimeoutsetInterval)仍会继续运行。也就是说,即使页面变为隐藏状态,定时器依然会按照设定的时间间隔执行其回调函数。

不过,用户可能不会看到这些执行结果,因为页面在后台,且可能会因为性能优化等原因受到限制。为了优化性能,很多开发者在检测到页面不可见时,会选择暂停或清除定时器。

你可以使用 visibilitychange 事件来检测页面的可见性状态变化,从而决定是否需要清除或暂停定时器。例如:

let timer;

function startTimer() {
    timer = setInterval(() => {
        console.log("Timer running");
    }, 1000);
}

document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden') {
        clearInterval(timer); // 停止定时器
    } else {
        startTimer(); // 重新开始定时器
    }
});

startTimer();

这样可以确保在页面隐藏时减少资源的消耗。

延伸 -- navigator.sendBeacon()

navigator.sendBeacon()  方法可用于通过 HTTP POST将少量数据异步传输到 Web 服务器。

它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:XMLHttpRequest)发送分析数据的一些问题。

语法

navigator.sendBeacon(url);
navigator.sendBeacon(url, data);

参数

返回值

当用户代理成功把数据加入传输队列时,sendBeacon()  方法将会返回 true,否则返回 false