打造全屏体验

我们可以轻松地打造沉浸式全屏网站和应用,但与网络上的任何网站一样,我们有多种方法可以实现这一点。现在,越来越多的浏览器支持全屏启动的“已安装 Web 应用”体验,这一点尤为重要。

让应用或网站进入全屏模式

用户或开发者可通过多种方式让 Web 应用进入全屏模式。

  • 请求浏览器进入全屏模式以响应用户手势。
  • 将应用安装到主屏幕。
  • 弄虚作假:自动隐藏地址栏。

请求浏览器进入全屏模式以响应用户手势

并非所有平台都相同。iOS Safari 没有全屏 API,但 Android 版 Chrome、Firefox 和 IE 11 及更高版本有提供。您构建的大多数应用都会组合使用全屏规范提供的 JS API 和 CSS 选择器。您在打造全屏体验时需要注意的主要 JS API 如下:

  • element.requestFullscreen()(目前在 Chrome、Firefox 和 IE 中添加前缀):以全屏模式显示元素。
  • document.exitFullscreen()(目前在 Chrome、Firefox 和 IE 中添加前缀。Firefox 改用 cancelFullScreen())取消全屏模式。
  • 如有任何元素处于全屏模式,document.fullscreenElement(目前在 Chrome、Firefox 和 IE 中添加前缀)会返回 true。

当应用进入全屏模式时,您无法再使用浏览器的界面控件。这会改变用户与您提供的体验互动的方式。他们没有“前进”和“后退”等标准导航控件,也没有“刷新”按钮这样的出路。您必须迎合这种情况。当浏览器进入全屏模式时,您可以使用某些 CSS 选择器来帮助您更改网站的样式和呈现方式。

<button id="goFS">Go fullscreen</button>
<script>
  var goFS = document.getElementById('goFS');
  goFS.addEventListener(
    'click',
    function () {
      document.body.requestFullscreen();
    },
    false,
  );
</script>

上面的示例有点人为设计;我将供应商前缀使用方面的复杂性全都隐藏了起来。

实际代码要复杂得多。Mozilla 创建了一个可用于切换全屏模式的非常有用的脚本。如您所见,与指定的 API 相比,供应商前缀的情况更为复杂和繁琐。虽然下面是稍微简化的代码,但仍然很复杂。

function toggleFullScreen() {
  var doc = window.document;
  var docEl = doc.documentElement;

  var requestFullScreen =
    docEl.requestFullscreen ||
    docEl.mozRequestFullScreen ||
    docEl.webkitRequestFullScreen ||
    docEl.msRequestFullscreen;
  var cancelFullScreen =
    doc.exitFullscreen ||
    doc.mozCancelFullScreen ||
    doc.webkitExitFullscreen ||
    doc.msExitFullscreen;

  if (
    !doc.fullscreenElement &&
    !doc.mozFullScreenElement &&
    !doc.webkitFullscreenElement &&
    !doc.msFullscreenElement
  ) {
    requestFullScreen.call(docEl);
  } else {
    cancelFullScreen.call(doc);
  }
}

我们网络开发者讨厌复杂。您可以使用的一个很好的高级抽象 API 是 Sindre SorhusScreenfull.js 模块,该模块将两个略有不同的 JS API 和供应商前缀统一到一个一致的 API 中。

全屏 API 提示

将文档设为全屏
正文元素全屏显示
图 1:使正文元素全屏显示。

您很自然地认为您将正文元素全屏显示,但如果您使用的是基于 WebKit 或 Blink 的渲染引擎,会发现这会产生一种奇怪的效果,即将正文宽度缩减至包含所有内容的最小尺寸。(Mozilla Gecko 没有问题。)

在文档元素上全屏显示
图 2:让文档元素全屏显示。

要解决此问题,请使用 document 元素而不是 body 元素:

document.documentElement.requestFullscreen();
将视频元素设置为全屏

让视频元素全屏显示的方法与使任何其他元素全屏显示的方法完全相同。您可以对视频元素调用 requestFullscreen 方法。

<video id="videoElement"></video>
<button id="goFS">Go Fullscreen</button>
<script>
  var goFS = document.getElementById('goFS');
  goFS.addEventListener(
    'click',
    function () {
      var videoElement = document.getElementById('videoElement');
      videoElement.requestFullscreen();
    },
    false,
  );
</script>

如果您的 <video> 元素未定义控件属性,则用户进入全屏模式后将无法控制视频。为此,建议您使用一个基本容器来封装视频和您希望用户看到的控件。

<div id="container">
  <video></video>
  <div>
    <button>Play</button>
    <button>Stop</button>
    <button id="goFS">Go fullscreen</button>
  </div>
</div>
<script>
  var goFS = document.getElementById('goFS');
  goFS.addEventListener(
    'click',
    function () {
      var container = document.getElementById('container');
      container.requestFullscreen();
    },
    false,
  );
</script>

这样做的灵活性更高,因为您可以将容器对象与 CSS 伪选择器结合使用(例如,隐藏“goFS”按钮)。

<style>
  #goFS:-webkit-full-screen #goFS {
    display: none;
  }
  #goFS:-moz-full-screen #goFS {
    display: none;
  }
  #goFS:-ms-fullscreen #goFS {
    display: none;
  }
  #goFS:fullscreen #goFS {
    display: none;
  }
</style>

通过使用这些模式,您可以检测全屏运行时间并相应地调整界面,例如:

  • 提供返回初始页的链接
  • 提供一种关闭对话框或回退的机制

从主屏幕以全屏模式启动网页

在用户导航至全屏网页时,无法启动全屏网页。浏览器供应商非常清楚,每次网页加载时都需要全屏体验,这会非常烦人,因此需要通过用户手势才能进入全屏模式。不过,供应商确实允许用户“安装”应用,而安装是向操作系统发出信号,用户想要在平台上以应用的形式启动。

在各大移动平台中,使用元标记或清单文件实现起来非常容易,如下所示。

iOS

自 iPhone 推出以来,用户便能够将 Web 应用安装到主屏幕上,并以全屏 Web 应用的形式启动。

<meta name="apple-mobile-web-app-capable" content="yes" />

如果 content 设置为 yes,则 Web 应用将以全屏模式运行;否则,不以全屏模式运行。默认行为是使用 Safari 显示 Web 内容。您可以使用 window.navigator.standalone 只读布尔值 JavaScript 属性来确定网页是否以全屏模式显示。

Apple

Chrome(Android 版)

Chrome 团队最近实现了一项功能,可在用户已将页面添加到主屏幕后指示浏览器以全屏模式启动页面。这与 iOS Safari 模式类似。

<meta name="mobile-web-app-capable" content="yes" />

您可以将 Web 应用设置为在设备的主屏幕上添加应用快捷方式图标,并使用 Android 版 Chrome 的“添加到主屏幕”菜单项以全屏“应用模式”启动。

Google Chrome

更好的选择是使用 Web 应用清单。

网络应用清单(Chrome、Opera、Firefox、Samsung)

Web 应用清单是一个简单的 JSON 文件,您(开发者)可以利用它控制在用户期望看到应用的区域(例如移动设备主屏幕)中如何向用户显示应用,指示用户可以启动哪些功能,更重要的是说明启动方式。未来,清单将支持您对自己的应用进行更多控制,但现在我们只侧重于如何启动您的应用。具体而言:

  1. 将清单的相关信息告知浏览器
  2. 说明启动方式

创建清单并将其托管在您的网站上后,您只需从包含您的应用的所有网页中添加链接标记,如下所示:

<link rel="manifest" href="/manifest.json" />

自 Android 38 版(2014 年 10 月)起,Chrome 就一直支持清单,并且可让您控制 Web 应用在安装到主屏幕上时的显示方式(通过 short_namenameicons 属性),以及当用户点击启动图标(通过 start_urldisplayorientation)时应如何启动应用。

示例清单如下所示。其中并未显示清单中可能包含的所有内容。

{
  "short_name": "Kinlan's Amaze App",
  "name": "Kinlan's Amazing Application ++",
  "icons": [
    {
      "src": "launcher-icon-4x.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "start_url": "/index.html",
  "display": "standalone",
  "orientation": "landscape"
}

此功能是完全渐进式的,可让您为支持该功能的浏览器用户打造更好、集成度更高的体验。

当用户将您的网站或应用添加到主屏幕时,他们有意将其当作应用来对待。这意味着,您的目标应该是将用户引导至应用的功能,而不是商品着陆页。例如,如果用户需要登录您的应用,那么该网页就是适合启动的页面。

实用工具应用

大多数实用程序应用都将立即受益。对于这些应用,您可能希望它们像移动平台上的所有其他应用一样独立启动。如需指示应用独立启动,请将以下内容添加到 Web 应用清单:

    "display": "standalone"
游戏

大多数游戏都将立即受益于清单。绝大多数游戏都希望强制按特定屏幕方向以全屏模式启动。

如果您开发的是纵向滚动游戏或 Flappy Birds 之类的游戏,那么您很可能希望游戏始终采用纵向模式。

    "display": "fullscreen",
    "orientation": "portrait"

另一方面,如果您要构建益智游戏或 X-Com 之类的游戏,那么您可能希望游戏始终使用横向屏幕方向。

    "display": "fullscreen",
    "orientation": "landscape"
新闻网站

在大多数情况下,新闻网站提供的是纯粹的基于内容的体验。当然,大多数开发者不会想到向新闻网站添加清单。您可以通过该清单定义要启动的内容(新闻网站的首页)和启动方式(全屏或正常浏览器标签页形式)。

选择方式取决于您以及您认为用户喜欢以何种方式访问您的体验。如果您希望网站具有您认为应该具有的所有浏览器 Chrome,可以将 display 设置为 browser

    "display": "browser"

如果您希望您的新闻网站感觉大多数以新闻为中心的应用都将其体验视为应用,并从界面中移除所有类似于 Web 的 Chrome,您可以将 display 设置为 standalone 来实现。

    "display": "standalone"

弄虚作假:自动隐藏地址栏

您可以通过按如下方式自动隐藏地址栏来“伪装全屏”功能:

window.scrollTo(0, 1);

这是一种非常简单的方法,它会加载网页并指示浏览器栏让开。遗憾的是,它并未标准化,也未得到充分支持。您还需要解决一些怪异行为。

例如,当用户导航返回页面时,浏览器通常会恢复页面上的位置。如果使用 window.scrollTo 替换了这一点,就会让用户感到厌烦。如需解决此问题,您必须将最后的位置存储在 localStorage 中,并处理极端情况(例如,如果用户在多个窗口中打开页面)。

用户体验指南

当您构建可以充分利用全屏模式的网站时,需要注意许多潜在的用户体验变化,才能打造出用户喜爱的服务。

不依赖于导航控件

iOS 没有硬件返回按钮或刷新手势。因此,您必须确保用户能够在应用内四处移动,而不会被锁定。

在所有主流平台上,都可以轻松检测您是以全屏模式还是安装模式运行。

iOS

在 iOS 上,您可以使用 navigator.standalone 布尔值来查看用户是否已从主屏幕启动。

if (navigator.standalone == true) {
  // My app is installed and therefore fullscreen
}

网络应用清单(Chrome、Opera、Samsung)

以安装式应用的形式启动时,Chrome 并不会以真正的全屏体验运行,因此 document.fullscreenElement 会返回 null,并且 CSS 选择器不起作用。

当用户通过您网站上的手势请求全屏时,可以使用标准全屏 API,其中包括 CSS 伪选择器,可让您调整界面以对全屏状态做出响应,如下所示

selector:-webkit-full-screen {
  display: block; // displays the element only when in fullscreen
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

如果用户从主屏幕启动您的网站,则 display-mode 媒体查询将设为 Web 应用清单中定义的内容。对于纯全屏模式,结果为:

@media (display-mode: fullscreen) {
}

如果用户以独立模式启动应用,display-mode 媒体查询将为 standalone

@media (display-mode: standalone) {
}

Firefox

当用户通过您的网站请求全屏或者用户以全屏模式启动应用时,所有标准全屏 API 都可用,包括 CSS 伪选择器,您可以通过它来调整界面以响应全屏状态,如下所示:

selector:-moz-full-screen {
  display: block; // hides the element when not in fullscreen mode
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

Internet Explorer

在 IE 中,CSS 伪类缺少连字符,但在其他方面与 Chrome 和 Firefox 类似。

selector:-ms-fullscreen {
  display: block;
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

规范

规范中的拼写与 IE 使用的语法一致。

selector:fullscreen {
  display: block;
}

selector {
  display: none; // hides the element when not in fullscreen mode
}

让用户享受全屏体验

有时,Fullscreen API 可能有点挑剔。浏览器供应商不想将用户锁定在全屏页面中,因此他们开发了相关机制,以便尽快摆脱全屏模式。这意味着您无法构建跨多个页面的全屏网站,原因如下:

  • 使用 window.location = "http://example.com" 以编程方式更改网址会摆脱全屏模式。
  • 用户点击您网页中的外部链接后将退出全屏模式。
  • 通过 navigator.pushState API 更改网址也会摆脱全屏体验。

如果您希望保持用户的全屏体验,有以下两种选择:

  1. 使用可安装的 Web 应用机制进入全屏模式。
  2. 使用 # 片段管理界面和应用状态。

通过使用 #syntax 更新网址 (window.location = "#somestate") 并监听 window.onhashchange 事件,您可以使用浏览器自己的历史记录堆栈管理应用状态的变化,允许用户使用其硬件返回按钮,或利用历史记录 API 提供简单的程序化返回按钮体验,如下所示:

window.history.go(-1);

让用户选择何时进入全屏模式

没有什么比网站执行意料之外的事情更让用户恼火。当用户进入您的网站时,不要试图诱骗他们进入全屏模式。

不要拦截第一个触摸事件并调用 requestFullscreen()

  1. 这很烦人。
  2. 浏览器可能决定在未来某个时间点提示用户是否允许应用占据全屏。

如果要全屏启动应用,请考虑采用每个平台的安装体验。

不得骚扰用户,让他们将应用安装到主屏幕

如果您计划通过已安装的应用机制提供全屏体验,请考虑用户。

  • 谨慎小心。使用横幅或页脚来告知用户他们可以安装应用。
  • 如果他们关闭了提示,请不要再次显示。
  • 在用户首次访问时,除非他们对您的服务感到满意,否则不太可能安装该应用。可以考虑在用户在您的网站上积极互动之后提示他们安装。
  • 如果用户经常访问您的网站,但并未安装您的应用,那么他们以后便不太可能安装您的应用。不要不断滥发电子邮件。

总结

虽然我们还没有完全标准化和实现的 API,但使用本文中介绍的一些指导,您可以轻松打造能够充分利用用户的整个屏幕的体验,而无论使用何种客户端。

反馈