js全屏模式轻松掌握[局部元素全屏展示]

32次阅读

共计 5085 个字符,预计需要花费 13 分钟才能阅读完成。

我第一次对网页全屏模式有概念,是那种网页播放视频的全屏播 放的那种。感觉很强,前几个星期有个需求也是关于全屏模式的,接触之后才知道全屏模式并不神秘,是个很容易掌握的技能 …

博客、前端积累文档、公众号、GitHub

CodePen Demo
地址:演示、code
进去看看,玩一下,本文将结合这个 demo 一起进行讲解。

全屏功能封装在一个类里面:
我把全屏模式封装在一个类里面,在代码中有详细的注释,如果有需要的话,直接把类拿出来,根据栗子和注释使用即可。
代码在 codepen 的 demo 里。
何谓全屏?
MDN 介绍:
使用提供的 API,让一个元素与其子元素,可以占据整个屏幕,并在此期间,从屏幕上隐藏所有的浏览器用户界面以及其他应用。
chrome 下的全屏表现:

全屏会隐藏标签栏, 书签栏
如果网页一开始不是全部撑开的形式,全屏下,也会将要全屏的元素充满整个屏幕

可以多层全屏,如栗子中一样,可以先左边全屏,然后红色全屏。在这种情况下退出全屏,只会退出红色全屏,退回到左边全屏的形式,所以页面依然是全屏模式。

进入全屏时,有一个默认的提示:’ 按 esc 即可退出全屏模式 ’,如下图显示:

当按 Esc 或调用退出全屏方法,退出全屏。标签栏和书签栏依然是隐藏的,网页上的元素恢复成原本的尺寸。要显示书签栏和标签栏,需要刷新一下页面。

全屏 API:
总共用到 6 个 API:

浏览器是否支持全屏模式:document.fullscreenEnabled

使元素进入全屏模式:Element.requestFullscreen()

退出全屏:document.exitFullscreen()

检查当前是否有节点处于全屏状态:document.fullscreenElement

进入全屏 / 离开全屏,触发事件:document.fullscreenchange

无法进入全屏时触发: document.fullscreenerror

浏览器前缀:
目前并不是所有的浏览器都实现了 API 的无前缀版本,所以我们需要针对不同浏览器,做一下 API 的兼容:
这是我在 demo 中做的浏览器兼容:
/**
* @description: 是否支持全屏 + 判断浏览器前缀
* @param {Function} fn 不支持全屏的回调函数 这里设了一个默认值
*/
isFullscreen(fn) {
let fullscreenEnabled;
// 判断浏览器前缀
if (document.fullscreenEnabled) {
fullscreenEnabled = document.fullscreenEnabled;
} else if (document.webkitFullscreenEnabled) {
fullscreenEnabled = document.webkitFullscreenEnabled;
this.prefixName = ‘webkit’;
} else if (document.mozFullScreenEnabled) {
fullscreenEnabled = document.mozFullScreenEnabled;
this.prefixName = ‘moz’;
} else if (document.msFullscreenEnabled) {
fullscreenEnabled = document.msFullscreenEnabled;
this.prefixName = ‘ms’;
}
if (!fullscreenEnabled) {
if (fn !== undefined) fn(); // 执行不支持全屏的回调
this.isFullscreenData = false;
}
}
我在实例化的时候进行一次判断浏览器是否支持全屏,然后保存浏览器前缀。
推荐这么做,因为如果每个 API 都要这样重复的判断浏览器前缀,那也太恶心了!
1. 浏览器是否支持全屏模式:document.fullscreenEnabled
document.fullscreenEnabled 属性返回一个布尔值,表示当前文档是否可以切换到全屏状态。
代码在上方浏览器前缀代码中给出了。
如果没有保存浏览器前缀的话,注意做一下不同浏览器前缀的兼容!下面不再强调。
2. 使元素进入全屏模式:Element.requestFullscreen()
/**
* @description: 将传进来的元素全屏
* @param {String} domName 要全屏的 dom 名称
*/
Fullscreen(domName) {
const element = document.querySelector(domName); // 获取 dom
const methodName =
this.prefixName === ”
? ‘requestFullscreen’
: `${this.prefixName}RequestFullScreen`; // API 前缀
element[methodName](); // 调用全屏
}
这就是我们实现全屏的 API,是不是超简单?
值得注意的是:调用此 API 并不能保证元素一定能够进入全屏模式

MDN:例如 <iframe> 元素具有 allowfullscreen 属性,可选择是否将其内容以全屏模式显示这种不被允许全屏的元素属于极少数情况,我试过可以将 button 全屏。

全屏请求必须在事件处理函数 (点击事件等) 中调用,否则将会被拒绝。在 demo 中有演示, 初始化直接全屏,会触发进入全屏失败回调。

3. 退出全屏:document.exitFullscreen()
介绍:
exitFullscreen() {
const methodName =
this.prefixName === ”
? ‘exitFullscreen’
: `${this.prefixName}ExitFullscreen`; // API 前缀
document[methodName](); // 调用
}
调用这个方法会让文档回退到上一个调用 Element.requestFullscreen()方法进入全屏模式之前的状态。
多层全屏
像 demo 中,先进入左边全屏,再进入红色全屏,即为:多层全屏的情况(虽然这种情况并不多)。
当出现多层全屏的情况,需要一层层的退出到页面最初始的情况,并不是调用一次 document.exitFullscreen()就恢复到页面最初始的样子。
4. 检查当前是否有节点处于全屏状态:document.fullscreenElement
fullscreenElement 属性返回正处于全屏状态的 Element 节点,如果当前没有节点处于全屏状态,则返回 null
/**
* @description: 检测有没有元素处于全屏状态
* @return 布尔值
*/
isElementFullScreen() {
const fullscreenElement =
document.fullscreenElement ||
document.msFullscreenElement ||
document.mozFullScreenElement ||
document.webkitFullscreenElement; // 有前缀的 f 是大写,没前缀是小写
if (fullscreenElement === null) {
return false; // 当前没有元素在全屏状态
} else {
return true; // 有元素在全屏状态
}
}
事实上,还有一个属性 document.fullscreen,返回一个布尔值,表示文档是否处于全屏模式。
两个方法效果是一样,但因为 IE 不支持这个属性,所以这里用的是 document.fullscreenElement
5. 进入全屏 / 离开全屏,触发事件:document.fullscreenchange
当我们进入全屏和离开全屏的时候,都会触发一个 fullscreenchange 事件。
MDN 注意:此事件不会提供任何信息,表明是进入全屏或退出全屏。
看了好久事件返回的信息,确实找不到一个值,表明这是在进入全屏,或者离开全屏!
可以说相当不人性化了!但我们可以通过检查当前是否有节点处于全屏状态,判断当前是否处于全屏模式。
/**
* @description: 监听进入 / 离开全屏
* @param {Function} enter 进入全屏的回调
* @param {Function} quit 离开全屏的回调
*/
screenChange(enter,quit) {
if (!this.isFullscreenData) return;
const methodName = `on${this.prefixName}fullscreenchange`;
document[methodName] = e => {
if (this.isElementFullScreen()) {
enter && enter(e); // 进入全屏回调
} else {
quit && quit(e); // 离开全屏的回调
}
};
}
注意:多层全屏的情况

先进入左边全屏(进入全屏回调),再进入红色全屏(进入全屏回调)
退出全屏, 此时退出红色全屏,左边仍是全屏(触发进入全屏回调)
出现这种情况,可以在点击按钮的时候,做一些状态限制。或者根据全屏事件返回的 dom 信息来进行判断。

6. 无法进入全屏时触发: document.fullscreenerror
进入全屏并不总是成功的,可能是技术原因,也可能是用户拒绝,我们在上文进入全文的 APIElement.requestFullscreen()部分讲过了。
比如全屏请求不是在事件处理函数中调用, 会在这里拦截到错误
/**
* @description: 浏览器无法进入全屏时触发
* @param {Function} enterErrorFn 回调
*/
screenError(enterErrorFn) {
const methodName = `on${this.prefixName}fullscreenerror`;
document[methodName] = e => {
enterErrorFn && enterErrorFn(e)
};
}
Css:全屏模式下的样式
chorme 70 下的默认会为正在全屏的 dom 添加两个 class:稍微看一下
默认设置黑色背景
:not(:root):-webkit-full-screen::backdrop {
position: fixed;
top: 0px;
right: 0px;
bottom: 0px;
left: 0px;
background: black; // 会将背景设为黑色的 如果你没为你的 dom 设置背景的话,全屏下会为黑色
}
默认样式:
:not(:root):-webkit-full-screen {
object-fit: contain;
position: fixed !important;
top: 0px !important;
right: 0px !important;
bottom: 0px !important;
left: 0px !important;
box-sizing: border-box !important;
min-width: 0px !important;
max-width: none !important;
min-height: 0px !important;
max-height: none !important;
width: 100% !important;
height: 100% !important;
transform: none !important;
margin: 0px !important;
}
全屏状态的 CSS:
全屏状态下,大多数浏览器的 CSS 支持:full-screen 伪类,只有 IE11 支持:fullscreen 伪类。使用这个伪类,可以对全屏状态设置单独的 CSS 属性。
以下 css 摘自阮一峰老师的 Fullscreen API:全屏操作
/* 针对 dom 的全屏设置 */
.div:-webkit-full-screen {
background: #fff;
}
/* 全屏属性 */
:-webkit-full-screen {}
:-moz-full-screen {}
:-ms-fullscreen {}
/* 全屏伪类 当前 chrome:70 不支持 */
:full-screen {
}
:fullscreen {
/* IE11 支持 */
}

结语
我们可以把全屏技术应用在 H5 游戏、信息流网站、视频等地方,下次再有全屏需求时,记住不要慌,回头看看过本文的栗子,把我封装的类拿出来直接用就可以啦!
希望看完的朋友可以点个喜欢 / 关注,您的支持是对我最大的鼓励。
博客、前端积累文档、公众号、GitHub
以上 2018.12.1
参考资料:
Fullscreen API:全屏操作
MDN

正文完
 0