記錄--Vue 網頁全屏

林恒發表於2024-06-13

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

在後臺系統中有一種常見的功能,點選按鈕將整個網頁全屏,再點選退出全屏。

瀏覽器提供了2種全屏方式,一種透過API在js中實現,另一種是按F11鍵進入全屏模式。

但F11進入的全屏模式優先順序更高,無法透過API退出。

基本知識

元素全屏

檢查可用性

為了判斷當前瀏覽器是否支援全屏,可以檢查只讀屬性document.fullscreenEnabled是否為true

進入全屏

網頁全屏可以使用Element.requestFullscreen()函式實現,可以將該元素全屏展示。

如果是移動端,全屏時會橫屏展示。

由於要將整個網頁全屏,所以直接使用根元素:

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()即可。

可以建立一個全屏按鈕元件如下:

<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>

本文轉載於:https://juejin.cn/post/7367552374334177331

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。

記錄--Vue 網頁全屏

相關文章