Vue 网页全屏

在后台系统中有一种常见的功能,点击按钮将整个网页全屏,再点击退出全屏。

浏览器提供了2种全屏方式,一种通过API在js中实现,另一种是按F11键进入全屏模式。

但F11进入的全屏模式优先级更高,无法通过API退出。

基本知识

元素全屏

检查可用性

document.fullscreenEnabled

为了判断当前浏览器是否支持全屏,可以检查只读属性是否为true

进入全屏

网页全屏可以使用Element.requestFullscreen()函数实现,可以将该元素全屏展示。

如果是移动端,全屏时会横屏展示。

由于要将整个网页全屏,所以直接使用根元素:

js 复制代码
document.documentElement.requestFullscreen()

检查状态

当调用过requestFullscreen()后,只读属性document.fullscreenElement将会等于对应当前全屏化的元素。

可以检查document.fullscreenElement是否等于document.documentElement来判断是否启用了网页全屏状态,避免之后退出其他元素的全屏状态。

退出全屏

调用document.exitFullscreen()可以退出最后一个元素的全屏状态。(如果有多个元素申请了全屏,则会退回上一个全屏状态)

此外,按EscF11也会退出全屏

事件

在触发全屏或退出全屏时(包括使用Esc、F11键退出),都会发出fullscreenchange事件。

浏览器全屏

除了通过命令让元素全屏,在浏览器中按F11键也会让网页窗口全屏,但要注意的是,通过该方式进入全屏时:

  • 不会修改document.fullscreenElement的值 例如没有调用过requestFullscreen(),按F11全屏后该值仍然是null
  • 全屏和退出时都不会发出fullscreenchange事件
  • 在按F11进入全屏时,会发出keydown事件,而退出全屏时则不会发出该事件
  • F11可以退出requestFullscreen()的全屏状态,但EscexitFullscreen()都不能退出F11的全屏状态

API全屏与浏览器全屏的冲突

在只使用API进入和退出全屏时,状态如下:

但先按F11进入全屏后:

  • 无法得知实际的全屏状态,进而无法显示正确的图标。
  • 由于全屏时再次通过requestFullscreen()全屏没有区别,也无法通过API退出,导致按钮失去作用。
  • 唯一退出全屏的方法就是再次按F11

解决方案

由于F11会导致全屏按钮失效和状态混乱,解决方案也很简单,禁用原生F11全屏,只用requestFullscreen()即可。

可以创建一个全屏按钮组件如下:

vue 复制代码
<template>
  <n-button v-if="enableFullscreen" @click="changeFullscreen">
    <n-icon size="18">
      <FullscreenExitFilled v-if="fullscreen" />
      <FullscreenFilled v-else />
    </n-icon>
  </n-button>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { FullscreenFilled, FullscreenExitFilled } from '@vicons/material'

// 当浏览器不支持全屏模式时,隐藏全屏按钮
const enableFullscreen = document.fullscreenEnabled
const fullscreen = ref(document.fullscreenElement === document.documentElement)

function changeFullscreen() {
  if (!fullscreen.value) {
    // 进入全屏
    if (document.fullscreenElement != null) {
      return
    }
    document.documentElement.requestFullscreen()
    return
  }
  // 退出全屏
  if (document.fullscreenElement !== document.documentElement) {
    return
  }
  document.exitFullscreen()
}

// 禁用F11按下后的原生全屏,改由组件控制
function onNativeFullscreenChange(e: KeyboardEvent) {
  if (e.key === 'F11') {
    e.preventDefault()
    changeFullscreen()
  }
}

// 通过监听事件来改变组件中的状态属性,而不是直接在调用API后更改,可避免通过按键退出时导致状态未变化
function updateFullscreenStatus() {
  fullscreen.value = document.fullscreenElement != null
}

onMounted(() => {
  document.addEventListener('keydown', onNativeFullscreenChange)
  document.addEventListener('fullscreenchange', updateFullscreenStatus)
})
onUnmounted(() => {
  document.removeEventListener('keydown', onNativeFullscreenChange)
  document.removeEventListener('fullscreenchange', updateFullscreenStatus)
})
</script>
相关推荐
장숙혜2 分钟前
ElementUi的tabs样式太难修改,自定义tabs标签页
前端·javascript
用户21411832636022 分钟前
dify案例分享-魔搭+Dify王炸组合!10分钟搭建你的专属 生活小助理
前端
工呈士3 分钟前
HTML与安全性:XSS、防御与最佳实践
前端·html·xss
WEI_Gaot6 分钟前
zustand 基础和进阶
前端·react.js
程序员Qian8 分钟前
从开发天气MCP服务入门什么是MCP
前端
用户20311966009610 分钟前
sheet的基本用法
前端
火星思想16 分钟前
都2025年了,还在问构建工具是干嘛的?
前端·前端框架·设计
杨进军19 分钟前
MutationObserver 实现 iframe 自适应高度
前端
火星思想20 分钟前
Promise 核心知识点(非基础)
前端·javascript·面试
前端大白话21 分钟前
炸裂!10个 React 实战技巧,让你的代码从“青铜”秒变“王者”
前端·javascript·react.js