页面全屏的实现和一些踩坑

1,371 阅读2分钟

简单介绍

正好做了个全屏的需求,碰见了一些坑点,遂记录一下。中间其实都是废话,可以直接拉到最后一节。

首先,页面全屏是个什么概念呢。打开一个浏览器,点击右上角中间那个键,浏览器会铺满整个屏幕,除了任务栏的区域,这叫窗口最大化。

当你按下F11(win)或 cmd+con+f并取消勾选 显示-始终在全屏显示工具栏时,会进入页面全屏状态。 当你使用web原生api dom.requestFullscreen使document或某个dom全屏时,会进入全屏状态。

页面全屏和全屏状态会使系统的操作拦隐藏,且全屏状态出于安全策略考虑,无法监听到ESC按键。

坑点

一开始在做这个需求的时候,我是这么想的:

从窗口化到全屏以及从全屏到窗口化,窗口一定会触发resize事件,我只需要监听这个事件,并在事件里判断当前是否处于全屏状态,这样也能解决全屏时无法监听到ESC的问题。

window.addEventListener('resize',handleResize)
function handleResize(){
    if(全屏){
        //全屏应该做的事
    }
    if(不全屏){
        //退出全屏应该做的事
    }
}

但很快发现一些问题,稍微具体一点的需求是这样:

在全屏后,页面的布局会发生一些改变,一些dom消失,一些dom的位置大小变化,事件监听变化;在退出全屏后,这些又恢复原样。

因为布局发生变化,在全屏后,还会触发riseze事件,而且不止一次,同样退出全屏也是。 而且在页面全屏状态进入全屏是不会触发riseze的(至少在win下的chorme不会)。 在handleRiseze方法里越改越乱后,我决定用其他的方法。

实现

进入全屏

使用requestFullscreen,顺便考虑一下浏览器兼容

const setFullscreen = (domEl)=>{

    const dom = domEl||document

    if (dom.requestFullscreen) dom.requestFullscreen()

    else if (dom.mozRequestFullScreen) dom.mozRequestFullScreen()

    else if (dom.webkitRequestFullScreen) dom.webkitRequestFullScreen()

}

判断是否在全屏

使用webkitIsFullScreen

const checkFullScreen = ()=>{

    return document.mozFullScreen ||document.webkitIsFullScreen ||document.webkitFullScreen

}

退出全屏

其实全屏状态下按ESC会自动退出全屏,这个方法是在需要通过其他按钮/按键退出全屏时用的

const exitFullScreen = ()=>{

if (document.exitFullscreen) document.exitFullscreen()

else if (document.mozCancelFullScreen) document.mozCancelFullScreen()

else if (document.webkitCancelFullScreen) document.webkitCancelFullScreen()

}

全屏状态变化监听

重点来了,当页面进入全屏/退出全屏时会触发fullscreenchange事件,而且只会触发一次。

const handleFullScreenChange = ()=>{

    if(checkFullScreen()){

        console.log('进入全屏!')

    }

    if(!checkFullScreen()){

        console.log('退出全屏!')

    }

}

document.addEventListener('fullscreenchange', handleFullScreenChange)

document.addEventListener('webkitfullscreenchange', handleFullScreenChange)

document.addEventListener('mozfullscreenchange', handleFullScreenChange)

OVER!