【译】使用 Fullscreen API 全屏展示内容

@JChehe 2018-01-28 10:26:32发表于 JChehe/blog

原文:Displaying Content in Full Screen using the Fullscreen API in JavaScript

译者注:若想直接应用 Fullscreen API,可直接使用 screenfull.js
另外,iOS 上 video 元素可能不兼容 Fullscreen API,但 iOS 有特定的方法处理,具体可查看 Apple Developer 相关文档。如:video 请求进入全屏 video.webkitEnterFullscreen()。此方法目前在 iOS 微信上有效。

大多数情况下,网站上的图片或视频等一些内容比较适合于全屏展示。而本文所指的全屏:是指占用用户整个屏幕,没有多余的浏览器边框和其他应用。Fullscreen API 的出现,让我们只需数行 JavaScript 代码即可使网站的任意一片内容成为焦点。如发布在你旅游博客上,并引以为豪的海岸景观(图片来自:PixaBay):

壮观的海岸景观(如需体验全屏功能,可到 原文体验,下同。)

全屏展示一个元素

Fullscreen API 的核心是 requestFullscreen() 方法,它能被文档上任意元素所调用,使自身沿四周展开,直至屏幕边界。

var featuredImg = document.getElementById('rockyshot')
if (featuredImg.requestFullscreen) {
    featuredImg.requestFullscreen()
}

IE 11+(含 11) 和桌面端 Chrome、Firefox 的所有较新版本均支持 Fullscreen API。需要注意的是,在编写本文时,仍需要添加内核前缀以获取被支持的相关方法和事件处理函数。以主要方法 requestFullscreen() 方法为例,最下面的三个版本是为了迎合三大主流浏览器:

requestFullscreen() (标准版本)
webkitRequestFullscreen()
mozRequestFullScreen() // 注意:Screen 的 S 为大写
msRequestFullscreen()

跨浏览器的 requestFullscreen() 方法

跨浏览器 Full Screen 函数:下面就创建一个跨浏览器版本的 requestFullscreen(),该函数能被页面上任何元素所使用,因此不必每次使用该函数时都进行 if/else 判断:

译者注:Fullscreen 的所有兼容性写法可引用或参考 screenfull.js

// 译者注:缺少对完全不兼容 requestFullscreen 的处理,下同。
function getReqFullscreen () {
    var root = document.documentElement
    return root.requestFullscreen || root.webkitRequestFullscreen || root.mozRequestFullScreen || root.msRequestFullscreen
}

// 用法:getRequestFullscreen().call(targetElement)

当每次调用 getRequestFullscreen() 时,我们都会得到浏览器支持的 requestFullscreen() 函数。而实际调用则需要通过 call() 指定上下文。即向 call() 传入我们想全屏展示的元素。

**案例:**页面中所有拥有 CSS 类名 canfullscreen 的图片被点击时都会全屏展示(图片来自 PixaBay):

菊花

var globalReqFullscreen = getReqFullscreen()

document.addEventListener('click', function (e) {
    var target = e.target
    if (target.tagName === 'IMG' && target.classList.contains('canfullscreen')) {
        globalReqFullscreen.call(target)
    }
})

易如反掌!

**注意:**若想让 document 自身全屏,则可使用 document.documentElement.requestFullscreen(),或通过跨浏览器函数:globalReqFullscreen.call(document.documentElement)

退出全屏

当有元素处于全屏状态时,用户有默认退出全屏的选项,即通过按 "esc" 或 "f11"。当然,你也可以通过 document.exitFullscreen() 实现同样的需求,其兼容性写法如下:

document.exitFullscreen() (标准方法)
document.webkitExitFullscreen()
document.mozCancelFullScreen() // 注意:Screen 的 S 为大写
document.msExitFullscreen()

需要注意的是:不像 requestFullscreen() 方法会存在于每个 DOM 元素上,以指定哪个元素进入全屏状态。而 exitFullscreen() 方法仅定义在 document 对象上。当它被调用时,会让全屏元素恢复到原有的位置上。

跨浏览器的 Exit 函数 :与上一章节相同,我们将会创建一个返回浏览器支持的 document.exitFullscreen() 函数,以便后续使用。

function getExitFullscreen() {
    return document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen
}
// 用法: getExitFullscreen.call(document)

**案例:**将下面代码添加到上一个案例中,双击任何带有 CSS 类名 canfullscreen 的图片都会从全屏返回到正常状态。

菊花

var globalExitFullscreen = getExitFullscreen()
document.addEventListener('dblclick', function (e) {
    var target = e.target
    if (target.tagName === 'IMG' && target.classList.contains('canfullscreen')) {
        globalExitFullscreen.call(document)
    }
}, false)

检查全屏状态

每当浏览器进入全屏模式时,document.fullscreenElement 对象(只读)都会引用当前展示的元素。否则,该对象返回 null

使用 document.fullscreenElement,我们能:

  • 判断浏览器目前是否处于全屏状态
  • 检查哪个元素正在被全屏展示

document.fullscreenElement 和其它 Fullscreen API 方法类似,都需要添加浏览器内核前缀:

document.fullscreenElement (标准方法)
document.webkitFullscreenElement
document.mozFullScreenElement // 注意:Screen 的 S 为大写
document.msFullscreenElement

**获取全屏元素的函数:**下面函数将会返回被支持的 document.fullscreenElement 对象:

function getFullscreenElement() {
    return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement
}
// 用法:getFullscreenElement()

下面是检查浏览器目前是否处于全屏状态,并且全屏展示的元素是图片:

if (getFullscreenElement() && getFullscreenElement().tagName === 'IMG') {
    console.log('An image is currently being shown full screen')
}

全屏与常规模式间的状态切换

document.fullscreenElement 对象的常见用法是动态切换元素的全屏与常规状态。

案例:下面通过单击操作切换图片的全屏状态。

菊花

var globalReqFullscreen = getReqFullscreen()
var globalExitFullscreen = getExitFullscreen()

document.addEventListener('click', function (e) {
    var target = e.target
    if (target.tagName === 'IMG' && target.classList.contains('canfullscreen')) {
    if (getFullscreenElement() === null) {
        globalReqFullscreen.call(target)
    } else {
        globalExitFullscreen.call(document)
    }
    }
}, false)

其他方法与事件处理函数

再补充剩余的一些对象和事件处理函数则是完整的 Fullscreen API。它们分别是:

  • document.fullscreenEnabled:如果页面可用于全屏模式,则返回 true。若没有为窗口插件或 <iframe> 元素显示设置 allowfullscreen 属性,则会在尝试全屏展示它们时返回失败。document.onfullscreenerror 事件也会被相应触发。
  • document.onfullscreenchange:每当浏览器进入或退出全屏模式时触发的事件处理函数。
  • document.onfullscreenerror:当请求全屏模式失败时触发的事件处理函数。

当然,以上属性或方法均需要加上内核前缀以获得被支持的版本。它们分别是:

document.fullscreenEnabled(标准方法) document.onfullscreenchange (标准方法) document.onfullscreenerror (标准方法)
document.webkitFullscreenEnabled document.onwebkitfullscreenchange document.onwebkitfullscreenerror
document.mozFullScreenEnabled document.onmozfullscreenchange document.onmozfullscreenerror
document.msFullscreenEnabled document.onmsfullscreenchange document.onmsfullscreenerror

要创建跨浏览器兼容的 document.onfullscreenchangedocument.onfullscreenerror,可根据浏览器对 requestFullscreen() 的兼容版本,映射支持的相应事件处理函数。

跨浏览器的 onfullscreenchange 事件: 下面是创建 document.onfullscreenchange 的一种方式:

function getOnFullscreenEvent() {
    var root = document.documentElement
    var fullscreenEvents = {
        'requestFullscreen': 'onfullscreenchange',
        'webkitRequestFullscreen': 'onwebkitfullscreenchange',
        'mozRequestFullScreen': 'onmozfullscreenchange',
        'msRequestFullscreen': 'onmsfullscreenchange'
    }
    
    for (var method in fullscreenEvents) {
        if (root[method]) {
            return fullscreenEvents[method]
        }
    }
    return undefined
}
// 用法:var globalOnFullscreenChange = getOnFullscreenEvent()
// document[globalOnFullscreenChange] = function(){...}

当调用 getOnFullscreenEvent 时,我们会得到被支持的 "onfullscreenchange" 字符串,如 "onwebkitfullscreenchange"。然后,将其绑定在 document 对象上:

var globalOnFullscreenChange = getOnFullscreenEvent()

document[globalOnFullscreenChange] = function () {
    console.log('You just entered or exit full screen')
}

需要注意的是,返回的字符串(如 "onfullscreenchange" 或 "onwebkitfullscreenchange")并不适用于 document.addEventListener(),其只适用于直接绑定在 document 对象上。

与全屏相关的 CSS

可通过 :fullscreen 伪选择器及其内核前缀修改元素在全屏模式下的样式:

:-webkit-full-screen {
    /*style for full screen element */
}
 
:-moz-full-screen {
    /*style for full screen element */
}
 
:-ms-fullscreen {
    /*style for full screen element */
}
 
:fullscreen { /* official selector */
    /*style for full screen element */
}

这对于创建目标元素及其后代元素全屏模式下的样式与常规模式下的不同,如 figure 元素含有一张可全屏查看的图片:

这对于目标元素及其后代元素在全屏与常规模式下展示不同的样式是非常有用的。如待全屏且含有图片的 figure

案例:

figure

figure 默认是 300px 宽,其子元素 img 则是 100% 宽。在全屏模式下,figure 的宽度伸展至 100%,而其子元素 img 的高度为 90vh(剩余空间留给下面的 caption 元素)。实现该功能的 CSS 如下:

<style>
 
figure{
    width: 300px;
    background: #eee;
    padding: 5px;
    cursor: pointer;
}
 
figure img{
    width: 100%;
    height: auto;
}
 
figure:-webkit-full-screen {
    width: 100%;
    text-align: center;
}
 
figure:-moz-full-screen {
    width: 100%;
    text-align: center;
}
 
figure:-ms-fullscreen {
    width: 100%;
    text-align: center;
}
 
figure:fullscreen { /* 标准选择器 */
    width: 100%;
    text-align: center;
}
 
figure:-webkit-full-screen img{
    width: auto;
    height: 90vh;
}
 
figure:-moz-full-screen img{
    width: auto;
    height: 90vh;
}
 
figure:-ms-fullscreen img{
    width: auto;
    height: 90vh;
}
 
figure:fullscreen img{
    width: auto;
    height: 90vh;
}
 
</style>

总结

以全屏方式展示某些内容,可作为加深印象和吸引用户的一个额外“补充”。如电子商务网站上的产品图片。
而 Fullscreen API 可帮助你实现这一点。