React项目实现全屏退出全屏的功能(并解决chrome下F11进入全屏后退出全屏API方法失效)

感谢原作者:参考原文地址为 https://blog.csdn.net/dream19921216/article/details/86596408

1. 问题说明
       网页全屏和退出全屏其实已经算的上一个很常见的功能了,那是不是直接用HTML5全屏API就没什么问题了,但是不要忘了键盘上的F11有着同样的功能,实际使用的时候就发现F11使网页进入全屏后,以HTML5的全屏API退出全屏就不管用了(不是一家,没商量好啊!)

2.页面全屏与退出全屏

// 根据浏览器可视区域高度与屏幕实际高度差值判断页面是否为全屏状态
 
// 取值17是为了处理页面内容出现滚动条的情况
var isFull = Math.abs(window.screen.height-window.document.documentElement.clientHeight) <= 17
 
window.onresize = function () {
    isFull = Math.abs(window.screen.height-window.document.documentElement.clientHeight) <= 17
}
 
// 阻止F11键默认事件,用HTML5全屏API代替
window.addEventListener('keydown', function (e) {
    e = e || window.event
    if (e.keyCode===122 && !isFull) {
        e.preventDefault()
        enterFullScreen()
    }
})
 
 
 // 打开浏览器全屏模式
 
   function enterFullScreen () {
      let el = document.documentElement
      let rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
      if (rfs) { // typeof rfs != "undefined" && rfs
        rfs.call(el)
      } else if (typeof window.ActiveXObject !== 'undefined') {
        // for IE,这里其实就是模拟了按下键盘的F11,使浏览器全屏
        let wscript = new ActiveXObject('WScript.Shell')
        if (wscript != null) {
          wscript.SendKeys('{F11}')
        }
      }
    }
 
    // 退出全屏
    function exitFullScreen () {
      let el = document
      let cfs = el.cancelFullScreen || el.mozCancelFullScreen || el.msExitFullscreen || el.webkitExitFullscreen || el.exitFullscreen
      if (cfs) { // typeof cfs != "undefined" && cfs
        cfs.call(el)
      } else if (typeof window.ActiveXObject !== 'undefined') {
        // for IE,这里和fullScreen相同,模拟按下F11键退出全屏
        let wscript = new ActiveXObject('WScript.Shell')
        if (wscript != null) {
          wscript.SendKeys('{F11}')
        }
      }
    },
View Code

3.问题解析
Document.exitFullscreen() 方法用于让当前文档退出全屏模式(原文表述不准确,详见备注)。调用这个方法会让文档回退到上一个调用Element.requestFullscreen()方法进入全屏模式之前的状态。

备注: 如果一个元素A在请求进去全屏模式之前,已经存在其他元素处于全屏状态,当这个元素A退出全屏模式之后,之前的元素仍然处于全屏状态。浏览器内部维护了一个全屏元素栈用于实现这个目的。

document.exitFullScreen()实际作用说明

 

  此文章为开发实际遇到问题记录,也是希望能帮助到遇到同类问题的码农们,如有描述错误,欢迎各位指正,看到必定更正!
---------------------------------------------

在react当中使用,创建fullScreen.js

src/utils/fullScreen.js

//全屏
// 打开浏览器全屏模式
/**
 * screenChange <Function> 为窗口变化的 的回调函数  参数为当前是否为全屏状态
 */
const init = (screenChange)=>{

    // 取值17是为了处理页面内容出现滚动条的情况
    let isFull = window.screen.height - window.document.documentElement.clientHeight <= 17;
    
    // 阻止F11键默认事件,用HTML5全屏API代替
    window.addEventListener('keydown', function (e) {
        e = e || window.event;
        if (e.keyCode===122 && !isFull) {
            e.preventDefault();
            enterFullScreen();
        }
    });
    //监听窗口变化
    window.onresize = function () {
        isFull = window.screen.height - window.document.documentElement.clientHeight <= 17;
        screenChange(isFull);
    }
};

//进入全屏
const enterFullScreen  = ()=>{
    let el = document.documentElement;
    let rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen || el.msRequestFullscreen
    if (rfs) { // typeof rfs != "undefined" && rfs
        rfs.call(el)
    } else if (typeof window.ActiveXObject !== 'undefined') {
        // for IE,这里其实就是模拟了按下键盘的F11,使浏览器全屏
        let wscript = new ActiveXObject('WScript.Shell');  //eslint-disable-line
        if (wscript != null) {
            wscript.SendKeys('{F11}')
        }
    }
};


// 退出全屏
const exitFullScreen = ()=>{
    let el = document;
    let cfs = el.cancelFullScreen || el.mozCancelFullScreen || el.msExitFullscreen || el.webkitExitFullscreen || el.exitFullscreen;
    if (cfs) { // typeof cfs != "undefined" && cfs
        cfs.call(el);
    } else if (typeof window.ActiveXObject !== 'undefined') {
        // for IE,这里和fullScreen相同,模拟按下F11键退出全屏
        let wscript = new ActiveXObject('WScript.Shell'); //eslint-disable-line
        if (wscript != null) {
            wscript.SendKeys('{F11}')
        }
    }
};

export default {
    init,
    enterFullScreen,
    exitFullScreen
}

在需要全屏的时候

这里演示采用react 组件的HOOK写法

 

import React, { useState, useEffect } from 'react';
import './index.less'; //样式
import FullScrenn from '../../utils/fullScreen';
//图标
const iconList = [
    {
        name: '全屏',
        icon: 'icont1a'
    },
    {
        name: '设置',
        icon: 'icont2a'
    },
    {
        name: '消息',
        icon: 'icont3a'
    },
];
function Headers(props) {
    //定义局部状态
    const [openMenu, setMenu] = useState(true);
    const [isScreenFull, setIsScreenFull] = useState(false); //是否全屏
    useEffect(()=>{
      //初始化
        FullScrenn.init(screenChange)
    }, [] );
    
    //屏幕变化
    const screenChange = (isFull)=>{
        console.log('是否全屏', isFull);
        setIsScreenFull(isFull);
    };

    //点击图标执行的事件
    const gotoIcon = (value, index) => {
        console.log('value, index', value, index);
        switch (value.name) {
            case '全屏':
                if(isScreenFull){
                    //退出全屏
                    FullScrenn.exitFullScreen();
                }else {
                    //进入全屏
                    FullScrenn.enterFullScreen();
                }
                break;
            default:
                break;
        }
    };
    
    return (
        <Header className="site-layout-background Headers">
            <div className='menu-action' onClick={() => {
                if (props.collapsed) {
                    props.handleOpenMenu();
                } else {
                    props.handleCloseMenu();
                }}}>
                <IconFont type={props.collapsed ? 'iconshrinkRight' : 'iconshrinkLeft'} />
            </div>
            
            <div className="searchModel">
                <IconFont className="searchIcon" type="iconic_so"></IconFont>
                <Input placeholder="搜索" style={{ float: 'left', width: '360px', height: '36px', paddingLeft: '30px', background: '#F9FAFB', border: '0px', borderRadius: '40px' }} />
            </div>
                
            <div className='user-pannel'>
                <div className="fricon">
                    {

                        iconList.map((item, index) =><Tooltip key={index} placement="bottom"
                                     title={isScreenFull && item.name === '全屏' ? '退出' + item.name : item.name}>
                                <a onClick={() => gotoIcon(item, index)}>
                                    <IconFont type={item.icon} className="icon"/>
                                </a>
                            </Tooltip>
                        )

                    }
                </div>
            </div>
        </Header>

    );
}

export default Headers;

 

效果图:

 

posted @ 2020-04-21 12:55  暗恋桃埖源  阅读(4516)  评论(0编辑  收藏  举报