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>
相关推荐
一 乐11 分钟前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
科技D人生21 分钟前
Vue.js 学习总结(20)—— Vue-Office 实战:word、pdf、excel、ppt 多种文档的在线预览
vue.js·word·vue-pdf·stylesheet·docx-preview·vue-office
vx1_Biye_Design22 分钟前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
vx_Biye_Design24 分钟前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计
hedley(●'◡'●)24 分钟前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
qq5_81151751525 分钟前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育26 分钟前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
百锦再26 分钟前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
hdsoft_huge28 分钟前
1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】
vue.js·spring boot·后端
CappuccinoRose1 小时前
JavaScript 学习文档(二)
前端·javascript·学习·数据类型·运算符·箭头函数·变量声明