进入全屏时,有一个 默认的提示 :'按esc即可退出全屏模式',如下图显示: ![](data:image/svg+xml;utf8,<?xml version="1.0"?><svg xmlns=" www.w3.org/2000/svg " version="1.1" width="1280" height="131"></svg>) 当按 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 ; } elseif (document.webkitFullscreenEnabled) { fullscreenEnabled = document.webkitFullscreenEnabled ; this.prefixName = 'webkit' ; } elseif (document.mozFullScreenEnabled) { fullscreenEnabled = document.mozFullScreenEnabled ; this.prefixName = 'moz' ; } elseif (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); // 获取domconst 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) { returnfalse; // 当前没有元素在全屏状态 } else { returntrue; // 有元素在全屏状态

    事实上,还有一个属性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支持 */
    

    完整DEMO

    <!DOCTYPE html> <meta charset="UTF-8"> <title></title> <style type="text/css"> .top { margin: 15px; .main { width: 100%; height: 1000px; display: flex; .left { width: 50%; height: 60%; background: gray; padding: 20px; .left-son { width: 80%; height: 50%; margin: 15px; background: red; .right { width: 50%; height: 60%; background: #dddddd; /* 针对dom的全屏设置 */ .left:-webkit-full-screen { background: #fff; /* 全屏属性 */ :-webkit-full-screen {} :-moz-full-screen {} :-ms-fullscreen {} /* 全屏伪类 当前chrome:70 不支持 */ :full-screen {} :fullscreen { /* IE11支持 */ </style> </head> <div class="top"> <button onclick="leftScreen()">左边全屏</button> <button onclick="rightScreen()">右边全屏</button> </div> <div class="main"> <div class="left"> <button onclick="redScreen()">红色全屏</button> <button onclick="exitScreen()">退出全屏</button> <div class="left-son"> <button onclick="exitScreen()">红色退出全屏</button> <span>左边的内容</span> </div> </div> <div class="right">右边的内容</div> </div> </body> <script type="text/javascript"> class fullScreen { * @description: 全屏初始化 * @param {Function} fn 用户浏览器不支持全屏的回调 constructor(fn) { this.prefixName = ""; // 浏览器前缀 this.isFullscreenData = true; // 浏览器是否支持全屏 this.isFullscreen(fn); * @description: 将传进来的元素全屏 * @param {String} domName 要全屏的dom名称 Fullscreen(domName) { const element = document.querySelector(domName); const methodName = this.prefixName === "" ? "requestFullscreen" : `${this.prefixName}RequestFullScreen`; element[methodName](); // 退出全屏 exitFullscreen() { const methodName = this.prefixName === "" ? "exitFullscreen" : `${this.prefixName}ExitFullscreen`; document[methodName](); * @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); // 离开全屏的回调 * @description: 浏览器无法进入全屏时触发,可能是技术原因,也可能是用户拒绝:比如全屏请求不是在事件处理函数中调用,会在这里拦截到错误 * @param {Function} enterErrorFn 回调 screenError(enterErrorFn) { const methodName = `on${this.prefixName}fullscreenerror`; document[methodName] = e => { enterErrorFn && enterErrorFn(e); * @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) { this.isFullscreenData = false; fn && fn(); // 执行不支持全屏的回调 * @description: 检测有没有元素处于全屏状态 * @return 布尔值 isElementFullScreen() { const fullscreenElement = document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; if(fullscreenElement === null) { return false; // 当前没有元素在全屏状态 } else { return true; // 有元素在全屏状态 let full = new fullScreen(() => { console.log("不支持"); full.screenError(e => { console.log("进去全屏失败:", e); // 全屏请求必须在事件处理函数中调用,否则将会被拒绝。 full.Fullscreen(".left"); // 触发进去全屏失败回调 const obj = { enter: e => { // 如果退出全屏 退出的还是全屏状态,将会触发进入全屏的回调,这种情况比较少 注意一下 console.log("进入全屏", e); quit: e => { console.log("退出全屏", e); // 通常不会出现嵌套的情况 full.screenChange(obj.enter, obj.quit); function leftScreen() { full.Fullscreen(".left"); function rightScreen() { full.Fullscreen(".right"); function redScreen() { full.Fullscreen(".left-son"); // 退出全屏 退出到上次的状态 function exitScreen() { full.exitFullscreen(); </script> </html> 复制代码

    结语

    我们可以把全屏技术应用在H5游戏、信息流网站、视频等地方,下次再有全屏需求时,记住不要慌,回头看看过本文的栗子,把我封装的类拿出来直接用就可以啦!