likes
comments
collection
share

页面全屏实现与实现过程中遇到的问题(弹框不显示)

作者站长头像
站长
· 阅读数 42

页面全屏实现与实现过程中遇到的问题(弹框不显示)

在日常的工作中,有些场景会需要实现全屏的效果,常见的全屏效果会分为全屏 以及页面全屏两种。

页面全屏

页面全屏就是只在浏览器视觉视口(浏览器可看到的区域)全屏。

页面全屏实现与实现过程中遇到的问题(弹框不显示)

实现

实现页面全屏的方式可以使用CSS的定位position: fixed和z-index实现。

.pageFullScreen {
    position: fixed;
    z-index: 10000;
    left:0;
    top: 0;
    width:100%;
    height: 100%;
}

上面的CSS可以实现页面全屏,但是还需要进行点击按钮的切换,在此使用vue实现。

// 在需要页面全屏的html标签中,使用v-bind绑定class,根据目前是否全屏的状态变量改变样式。
:class="{'pageFullScreen': bol}" // bol是目前是否全屏的状态变量

全屏

这种就是就是页面会占满整个屏幕,与浏览器大小无关,无论浏览器放大还是缩小都会占满整个屏幕,按ESC它可以退出全屏,如下图。

页面全屏实现与实现过程中遇到的问题(弹框不显示)

实现

想要实现占满全部屏幕有相应的API可以实现,下面可以看下相关代码。

// 进入全屏方法
export const enterFullscreen = (el) => {
    // W3C
    if (el.requestFullscreen) {
        el.requestFullscreen();
    }
    // 火狐
    else if (el.mozRequestFullScreen) {
        el.mozRequestFullScreen();
    }
    // 谷歌
    else if (el.webkitRequestFullScreen) {
        el.webkitRequestFullScreen();
    }
    // IE
    else if (el.msRequestFullscreen) {
        el.msRequestFullscreen();
    }
};

可以看到实现还是比较简单的,只要传需要全屏的DOM元素再调用API可以实现全屏效果了。

就算自己没有实现退出全屏,点击键盘ESC也是可以退出全屏的,不过最好还是自己再写一个方法实现退出全屏给按钮点击使用。

// 退出全屏方法
export const exitFullscreen = () => {
    if (document.exitFullscreen) {
        document.exitFullscreen();
    } 
    else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
    } 
    else if (document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen();
    } 
    else if (document.msExitFullscreen) {
        document.msExitFullscreen();
    }
};

除此之外我们还可以检测当前是否是全屏状态,方便进行一些业务的判断。

// 检测是否全屏,根据返回的true或false判断,全屏:true,非全屏:false
export const isFullScreenStatus = () => {
    return document.isFullScreen || 
    document.mozIsFullScreen || 
    document.webkitIsFullScreen;
};

以上就可以实现一个占满全部屏幕的效果了。

全屏中存在的问题

有时候我们在业务中需要的是页面中的某一部分实现全屏效果,实现这个其实只需要传入这部分的DOM元素就可以了,不过这有时候会造成一个问题,就是页面虽然全屏了,但是点击页面上的弹框或者下拉框这类组件却发现没有弹出来。

其实并不是这类组件点击了没有反应,而是这类弹框在的DOM并不在该全屏的DOM下,而是在body下,而全屏的情况下DOM的层级是最高的 (设置z-index都无济于事) ,因此不在全屏DOM下的弹框类组件弹出来了也会被全屏给覆盖,导致了就算是弹框已弹出来了也看不到。

比如element ui库的 Dialog 对话框组件在使用append-to-body这个属性时对话框组件的DOM就是在body下面;在后面统一用body弹框表示这类组件

页面全屏实现与实现过程中遇到的问题(弹框不显示)

解决方案

以下的代码是Vue3的语法

方案一

解决此问题的方法最好就是将该类型组件的DOM加到需要全屏的元素下,这种合适body弹框较少的页面

具体实现

点击打开弹框的按钮时执行以下代码。

// 关键代码
nextTick(() => {
    dialogTableVisible.value = true  // 示例:打开Dialog对话框,具体根据自己情况调整
    if (document.querySelector('.el-overlay')) {
        // 将Dialog的DOM元素添加到需要全屏的元素下,这是我的示例,具体根据自己情况调整
        panelRef.value.appendChild(document.querySelector('.el-overlay'));
    }
})
方案二

上面的方案比较合适body弹框较少的页面,如果是碰到body弹框较多或者是页面中引入了其他组件,在这些组件中存在着不知数量的body弹框,那么方案一的工作量就会变得比较多比较复杂。

方案二可以使用页面全屏加上全屏实现。

思路:首先将需要全屏的DOM实现页面全屏,再将body实现全屏,这样就算body弹框是在body下也可以显示出来。

具体实现

需要注意监听窗口的变化以及键盘F11的全屏冲突,注意看代码中的注释

<script setup>
    import { ref, reactive, onMounted, nextTick } from 'vue'
    // 这部分方法的代码上面已经有了
    import { enterFullscreen, exitFullscreen, isFullScreenStatus } from './js/index'
    name: 'fullScreen'
    
    let bol = ref(false)
    const panelRef = ref(null) // 获取全屏元素的ref

    onMounted(() => {
        window.addEventListener("keydown", keydown, true); //监听键盘按钮
        window.addEventListener('resize', resize) // 监听窗口大小变化
    })

    // 监听窗口大小变化,执行回调,当全屏状态按键盘ESC时会退出全屏状态,这时也要退出页面全屏状态
    // 不监听键盘ESC事件是因为全屏状态时,点击键盘ESC不触发该按键的事件监听
    const resize = () => {
        if (!isFullScreenStatus()) {
            bol.value = false // 退出页面全屏状态
        }
    }

    //监听键盘按钮,执行回调,为了防止与键盘F11的全屏冲突
    const keydown = (e) => {
        if (e.keyCode === 122) { // 键盘F11的码
            e.returnValue = false // 阻止F11原本的全屏事件
            onPageFullScreen() // 触发自己实现的全屏的方法
        }
    }

    // 全屏按钮函数
    const onPageFullScreen = () => {
        if(bol.value) {
            exitFullscreen() // 退出全屏
        }

        if(!isFullScreenStatus()) {
            // 全屏
            enterFullscreen(document.querySelector('body')) // 获取body的DOM传递给全屏方法实现全屏
            bol.value = !bol.value
        }
    }

</script>

总结

这些都是本人在项目中的需求实现与遇到的问题,不一定适用全部人,不过如果有适用的场景可以借鉴一下,代码写的一般,可以借鉴思路。

转载自:https://juejin.cn/post/7210387904748191799
评论
请登录