• 封装class类一次性解决全屏问题


    前言

    这里先给项目地址:地址

    支持全屏的api

    1. 浏览器是否支持全屏模式:document.fullscreenEnabled
    2. 使元素进入全屏模式:Element.requestFullscreen()
    3. 退出全屏:document.exitFullscreen()
    4. 检查当前是否有节点处于全屏状态:document.fullscreenElement
    5. 进入全屏/离开全屏,触发事件:document.fullscreenchange
    6. 无法进入全屏时触发: document.fullscreenerror

    浏览器前缀:

    目前并不是所有的浏览器都实现了API的无前缀版本,所以我们需要针对不同浏览器,做一下API的兼容:

    我们需要写成类的形式:

    /**
     * @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;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    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](); // 调用全屏
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 退出全屏:document.exitFullscreen()

    exitFullscreen() {
      const methodName =
        this.prefixName === ''
          ? 'exitFullscreen'
          : `${this.prefixName}ExitFullscreen`; // API 前缀
      document[methodName](); // 调用
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

    /**
     * @description: 检测有没有元素处于全屏状态
     * @return 布尔值
     */
    isElementFullScreen() {
      const fullscreenElement =
        document.fullscreenElement ||
        document.msFullscreenElement ||
        document.mozFullScreenElement ||
        document.webkitFullscreenElement; // 有前缀的f是大写,没前缀是小写
      if (fullscreenElement === null) {
        return false; // 当前没有元素在全屏状态
      } else {
        return true; // 有元素在全屏状态
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    事实上,还有一个属性document.fullscreen,返回一个布尔值,表示文档是否处于全屏模式。

    两个方法效果是一样,但因为IE不支持这个属性,所以这里用的是document.fullscreenElement.

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

    当我们进入全屏和离开全屏的时候,都会触发一个fullscreenchange事件。

    注意:此事件不会提供任何信息,表明是进入全屏或退出全屏。

    /**
     * @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); // 离开全屏的回调
        }
      };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    注意:多层全屏的情况

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

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

    比如全屏请求不是在事件处理函数中调用,会在这里拦截到错误:

    /**
     * @description: 浏览器无法进入全屏时触发
     * @param {Function} enterErrorFn 回调
     */
    screenError(enterErrorFn) {
      const methodName = `on${this.prefixName}fullscreenerror`;
      document[methodName] = e => {
        enterErrorFn && enterErrorFn(e)
      };
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Css: 全屏模式下的样式

    1. 默认设置黑色背景
    :not(:root):-webkit-full-screen::backdrop {
      position: fixed;
      top: 0px;
      right: 0px;
      bottom: 0px;
      left: 0px;
      background: black; // 会将背景设为黑色的 如果你没为你的dom设置背景的话,全屏下会为黑色
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 默认样式:
    :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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    全屏状态的CSS:

    全屏状态下,大多数浏览器的CSS支持:full-screen伪类,只有IE11支持:fullscreen伪类。使用这个伪类,可以对全屏状态设置单独的CSS属性。

    /* 针对dom的全屏设置 */
    .div:-webkit-full-screen {
      background: #fff;
    }
    /* 全屏属性 */
    :-webkit-full-screen {}
    :-moz-full-screen {}
    :-ms-fullscreen {}
    /* 全屏伪类 当前chrome:70 不支持 */
    :full-screen {
    }
    :fullscreen {
      /* IE11支持 */
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    参考资料:阮一峰老师的Fullscreen API:全屏操作

    这里是一条华丽的分割线,讲完原理开始实战

    项目的html

    index.html:

    DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link rel="stylesheet" href="./index.css" />
      <title>Documenttitle>
    head>
    
    <body>
      <iframe src="https://codesandbox.io/s/" id="iframe-one" name="iframe-one
          width=" 100%" height="200" scrolling="no" frameborder="0">iframe>
      <img src="vscode.svg" onclick="iframeScreen()" id="vscode" width="100" height="100" alt="">
      <script src="./index.js">script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    项目中的css

    index.css:

    #iframe-one {  // 随便是什么元素,一开始不展示元素
      display: none;
    }
    /* 针对dom的全屏设置 */
    .left:-webkit-full-screen {
      background: #fff;
    }
    /* 全屏属性 */
    :-webkit-full-screen {
    }
    :-moz-full-screen {
    
    }
    :-ms-fullscreen {
    }
    /* 全屏伪类 当前chrome:70 不支持 */
    :full-screen {
    
    }
    :fullscreen {
      /* IE11支持 */
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    封装完成的js文件

    以后无论遇到什么全屏问题都可以用改封装得class

    index.js:

    class fullScreen {
      constructor(fn) {
        // fn是失败的回调函数
        this.prefixName = ''; // 浏览器前缀
        this.isFullscreenData = true; // 浏览器支持全屏
        this.isFullscreen(fn);
      }
      /**
       * @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;
        }
      }
    
      /**
       * @description: 将传进来的元素全屏
       * @param {String} domName 要全屏的dom名称
       */
      Fullscreen(element) {
        const methodName =
          this.prefixName === ''
            ? 'requestFullscreen'
            : `${this.prefixName}RequestFullScreen`; // API前缀
        element[methodName](); // 调用全屏
      }
    
      // 退出全屏
      exitFullscreen() {
        const methodName =
          this.prefixName === ''
            ? 'exitFullscreen'
            : `${this.prefixName}ExitFullscreen`; // API 前缀
        document[methodName](); // 调用
      }
    
      /**
       * @description: 检测有没有元素处于全屏状态
       * @return 布尔值
       */
      isElementFullScreen() {
        const fullscreenElement =
          document.fullscreenElement ||
          document.msFullscreenElement ||
          document.mozFullScreenElement ||
          document.webkitFullscreenElement; // 有前缀的f是大写,没前缀是小写
        if (fullscreenElement === null) {
          return false; // 当前没有元素在全屏状态
        } else {
          return true; // 有元素在全屏状态
        }
      }
    
      /**
       * @description: 监听进入/离开全屏
       * @param {Function} enter 进入全屏的回调
       *  @param {Function} quit 离开全屏的回调
       */
      screenChange(enter, quit) {
        if (!this.isFullscreenData) return;
        const methodName = `on${this.prefixName}fullscreenchange`;
        document[methodName] = (e) => {
          console.log(e);
          if (this.isElementFullScreen()) {
            enter && enter(); // 进入全屏回调
          } else {
            quit && quit(); // 离开全屏的回调
          }
        };
      }
    
      /**
       * @description: 浏览器无法进入全屏时触发
       * @param {Function} enterErrorFn 回调
       */
      screenError(enterErrorFn) {
        const methodName = `on${this.prefixName}fullscreenerror`;
        document[methodName] = (e) => {
          enterErrorFn && enterErrorFn(e);
        };
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    对元素一开始显示或者隐藏处理

    这里可以这样处理调用screenChange方法,里面执行进入屏幕的回调和离开屏幕的回调,既进入显示,离开隐藏

    index.js:

    let full = new fullScreen(() => {
      console.log('不支持');
    });
    
    const iframe = {
      enter: function (element) {
        // 显示
        element.style.display = 'block';
      },
      quit: function (element) {
        // 隐藏
        element.style.display = 'none';
      },
    };
    
    function iframeScreen() {
      const element = document.querySelector('#iframe-one');
      full.Fullscreen(element);
      full.screenChange(
        () => iframe.enter(element),
        () => iframe.quit(element)
      );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    2023年Q3线上生鲜水产数据分析:市场不景气,销额同比下滑44%
    【手把手带你学JavaSE】第三篇:运算符和程序逻辑控制
    谱定理等周边定理
    【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路
    美国RAKsmart:裸机云站群服务器配置详解
    浏览器输入网址后发生了什么?
    “MJiangSports“ app Tech Support(URL)
    计算机网络(TCP协议)
    实验三 数字加法器的设计【Verilog】
    Python字典和集合操作指南:创建、获取值、修改和删除键值对,复制和遍历方法全解析
  • 原文地址:https://blog.csdn.net/weixin_50789156/article/details/126089849