早期,浏览器上并不是标签式的,如今,我们会发现所有浏览器都提供了这个功能。作为一个开发人员,我正常情况下会同时打开 10-15 个标签,有时候最多可能会达到25-30 个。

这个 API 为何而来?

以前,无法判断哪个标签是激活的,哪个不是。现在有了 HTML5 Visibility API,我们可以检测用户是否正在浏览我们的网页。

我们将在本文中学习如何使用 HTML5 Visibility API,展示下如何检测我们页面的状态。在 demo 中,我们将根据用户页面的可视状态修改文档的标题。

检测页面的可视状态

这个 API 为我们带来了两个 document 上的属性,document.visibilityState 和 document.hidden, 这个两个属性实现了不同的功能。

document.visibilityState 有四个不同的值:

  • hidden:页面不可见
  • prerender:页面在后台加载的,对用户不可见
  • visible:页面可见
  • unloaded:页面即将关闭(用户正在从当前页面跳转到其他页面)

document.hidden 是一个布尔属性,页面可见是为 false,页面不可见时为 true。

现在我们就可以在网页对用户不可见之后控制我们网站的行为。

马上我们就可以接触可见性属性了,不过现在先学习一下事件监听,这样就可以在页面可见性变化时收到通知。这个事件就是 visibilitychange,下面是一个简单的示例如何使用这个事件:

document.addEventListener('visibilitychange', function(event) {
  if (!document.hidden) {
    // The page is visible.
  } else {
   // The page is hidden. 
  }
});

这段代码是一个简单的实例,展示如何利用这个事件来了解当前页面的状态。但你要知道,这些属性和方法都需要加上 Vendor前缀,因为这些事件和属性在某些浏览器上是有前缀的。现在我们来看下面这段,跨浏览器的写法:

// Get Browser-Specifc Prefix
function getBrowserPrefix() {

  // Check for the unprefixed property.
  if ('hidden' in document) {
    return null;
  }

  // All the possible prefixes.
  var browserPrefixes = ['moz', 'ms', 'o', 'webkit'];

  for (var i = 0; i < browserPrefixes.length; i++) {
    var prefix = browserPrefixes[i] + 'Hidden';
    if (prefix in document) {
      return browserPrefixes[i];
    }
  }

  // The API is not supported in browser.
  return null;
}

// Get Browser Specific Hidden Property
function hiddenProperty(prefix) {
  if (prefix) {
    return prefix + 'Hidden';
  } else {
    return 'hidden';
  }
}

// Get Browser Specific Visibility State
function visibilityState(prefix) {
  if (prefix) {
    return prefix + 'VisibilityState';
  } else {
    return 'visibilityState';
  }
}

// Get Browser Specific Event
function visibilityEvent(prefix) {
  if (prefix) {
    return prefix + 'visibilitychange';
  } else {
    return 'visibilitychange';
  }
}

兼容全部浏览器的属性和事件已经准备好了,现在我们就改一下之前的代码:

// Get Browser Prefix
var prefix = getBrowserPrefix();
var hidden = hiddenProperty(prefix);
var visibilityState = visibilityState(prefix);
var visibilityEvent = visibilityEvent(prefix);

document.addEventListener(visibilityEvent, function(event) {
  if (!document[hidden]) {
    // The page is visible.
  } else {
   // The page is hidden. 
  }
});

在哪里使用这个 API?

有很多场景都可以考虑这个使用这个 API:

  1. 比如说你在开发一个控制面板页面,这个页面会定时,比如说两分钟,从某些 RSS feed 或者 API拉取详细数据。我们可以在页面对用户不可见时(也就是用户没在看着页面时)显示对 RSS feed 或者 API 的请求
  2. 还有图片轮播,当页面不可见后,我们可以限制轮播的移动
  3. 类似的方式,只有在页面不可见时,才给用户显示 HTML Notification

到这我们已经看过如何使用代码调用 HTML5 页面 Visibility API了,接下来就开始动真格了。

动真格

  • Demo 1:使用页面 Visibility API 修改页面标题 查看 Demo
  • Demo 2:当页面影藏后,限制从服务端获取数据

在这个示例中,我们将试着限制从服务器刷新信息,除非用户正在看着这个页面。我假设在你的页面中已经添加了jQuery。这里我就是简单的自增一个计数器,不过可以替换成访问服务器。

HTML

<!-- This element will show updated count -->
<h1 id="valueContainer">0</h1>

JavaScript

<script type="text/javascript">

    // Get Browser Prefix
    var prefix = getBrowserPrefix();
    var hidden = hiddenProperty(prefix);
    var visibilityState = visibilityState(prefix);
    var visibilityEvent = visibilityEvent(prefix);

    var timer = null;

    function increaseVal() {
        var newVal = parseInt($('#valueContainer').text()) + parseInt(1);
        $('#valueContainer').text(newVal);
        document.title = newVal + ': Running'; 

        timer = setTimeout(function() {
            increaseVal();
        }, 1);
    }

    // Visibility Change 
    document.addEventListener(visibilityEvent, function(event) {
          if (document[hidden]) {
              clearTimeout(timer);
              var val = parseInt($('#valueContainer').text());
              document.title = val + ': Pause'; 
          } else {
              increaseVal();  
          }
    });

    increaseVal();

</script>

查看 Demo

浏览器支持

如果你想看看浏览器对这个 API 的支持情况,我建议你可以看看 Can I use?。但是如果想通过编程检测浏览器是否支持,你可以看看这篇文章Detect HTML5 Features。目前几乎所有主要的、最新版的浏览器都对这个 API 有不错的支持。

总结

我要说我们已经有一个非常棒的 API,仅仅包括两个属性和一个事件。我们可以非常容易地把它集成到现有的项目中,为我们的用户提供更好的体验。最基本的,我们可以在网站对用户不可见后,控制它的行为。

原文:HTML5 Page Visibility API

0
推荐阅读