之前看到一个页面根据用户是否定位当前标签来更改 title ,觉得有些意思,然后特意了解了一下实现原理,发现是和 Page Visibility API 相关的,并且在前端页面优化方面也能用到,就整理一下相关的知识。整体的思路是:
js控制标签title的改变 -> 判断用户是否可见情况下 -> Page Visibility API -> 可以应用及可能优化的地方。

Page Visibility API

Page Visibility API 是 W3C 制定的一个页面是否可见的草案(Page Visibility), 截止到总结这部分知识点 Page Visibility 上一个更新的时间是 2018年10月17日。
Page Visibility API 具有通用性,无论是移动端还是Web端均可适用。Page Visibility API 主要包括以下三个属性:

下面针对三个属性对应取值作出详细说明。

document.visibilityState 属性值

document.visibilityState 属性 当前版本可以取以下三个值:

enum VisibilityState {
  "hidden", "visible", "prerender"
};

也就是说,现在常用的共有 三种值 hidden, visible, prerender。因为预渲染功能并非所有浏览器都支持,这个使用时需要注意兼容性。

document.visibilityState 属性取 “hidden” 值出现的情况有以下几种:

在页面关闭前,document.visibilityState 属性值一定会变成 “hidden”,需要注意的是,该属性只针对顶层窗口,并不影响内嵌页面的可见性。

document.hidden 属性值

该属性值是一个遗留的问题 (Document.hidden is historical. Use Document.visibilityState instead.)。
只有在 document.visibilityState 为 “visible” 时,document.hidden 属性为 “false”,其他情况都是 “true”。

Support for hidden attribute is maintained for historical reasons. Developers should use visibilityState where possible.

所以啊,如果可能,尽量使用 document.visibilityState 这个属性。

visibilitychange 事件

当 document.visibilityState 属性值发生变化时,就会触发 visibilitychange 事件。可以使用添加事件监听器的方式(document.addEventListener()),或者监听 document.onvisibilitychange 属性值的变化,来监听页面的变化。
最常用的用法如下所示:

// page visibility API
document.addEventListener('visibilitychange', function () {
    // when user leaves this page
    if (document.visibilityState == 'hidden') {
        document.title = "Don't leave me alone~";
    }

    // when user comes back
    if (document.visibilityState == 'visible') {
        document.title = "JavaScript~";
    }
})

ruanyifeng博客 里面也给出了暂停播放视频的示例代码:

// Pause video play when visibilitychange

let vedioElement = document.getElementById('vedio');
document.addEventListener('visibilitychange', changeVedioState);

function changeVedioState() {
    if (document.visibilityState == 'hidden') {
        vedioElement.pause();
    } else if (document.visibilityState == 'visible') {
        vedioElement.play();
    }
}

此外,也可以使用 document.onvisibilitychange 来完成相应的监听:

document.onvisibilitychange = function (){
// when user leaves this page
    if (document.visibilityState == 'hidden') {
        document.title = "Don't leave me alone~(つд⊂)";
    }

// when user comes back
    if (document.visibilityState == 'visible') {
        document.title = "JavaScript~";
    }
}

对于针对浏览器兼容性,所给出的添加前缀的方法,也可以参考:

function getVisibilityState() {
    var prefixes = ['webkit', 'moz', 'ms', 'o'];
    // Chrome/Safari -> webkit
    // Firefox -> moz
    // IE -> ms
    // Opera -> o
    if ('visibilityState' in document) return 'visibilityState';
    for (var i = 0; i < prefixes.length; i++) {
        if ((prefixes[i] + 'VisibilityState') in document)
            return prefixes[i] + 'VisibilityState';
        }
        return null;
    }
}

即监听事件,再获取状态(添加特定前缀),根据状态作出判断。
此外我又查了 visibilityState 的兼容性,基本就剩 IE 旧版本 和 Opera 的没兼容了。

Can I Use visibilityState

Upload Page

页面卸载一般指的是:

以上三种情况都可当作页面卸载。
监听页面卸载之前常用的方法有监听 “pagehide”、”beforeunload”、”unload” 事件, 而监听 visibilitychange 事件 可以完全替代前面的方法。

Page Visibility API可带来性能优化

使用 Page Visibility API 可以给页面带来以下几方面的性能优化相关的好处:

所以,JavaScript 监听标签页的切换Title 主要是通过 使用 Page Visibility API 监听页面是否可见从而改变title 实现的。 过两天也给索引页加上这个,增强用户交互的体验~

Reference Sites