🧑💻 寫在開頭
點贊 + 收藏 === 學會🤣🤣🤣
在後臺系統中有一種常見的功能,點選按鈕將整個網頁全屏,再點選退出全屏。
瀏覽器提供了2種全屏方式,一種透過API在js中實現,另一種是按F11
鍵進入全屏模式。
但F11進入的全屏模式優先順序更高,無法透過API退出。
基本知識
元素全屏
檢查可用性
為了判斷當前瀏覽器是否支援全屏,可以檢查只讀屬性document.fullscreenEnabled是否為true
。
進入全屏
網頁全屏可以使用Element.requestFullscreen()函式實現,可以將該元素全屏展示。
如果是移動端,全屏時會橫屏展示。
由於要將整個網頁全屏,所以直接使用根元素:
document.documentElement.requestFullscreen()
檢查狀態
當呼叫過requestFullscreen()
後,只讀屬性document.fullscreenElement將會等於對應當前全屏化的元素。
可以檢查document.fullscreenElement
是否等於document.documentElement
來判斷是否啟用了網頁全屏狀態,避免之後退出其他元素的全屏狀態。
退出全屏
呼叫document.exitFullscreen()可以退出最後一個元素的全屏狀態。(如果有多個元素申請了全屏,則會退回上一個全屏狀態)
此外,按Esc
、F11
也會退出全屏
事件
在觸發全屏或退出全屏時(包括使用Esc、F11鍵退出),都會發出fullscreenchange
事件。
瀏覽器全屏
除了透過命令讓元素全屏,在瀏覽器中按F11
鍵也會讓網頁視窗全屏,但要注意的是,透過該方式進入全屏時:
- 不會修改
document.fullscreenElement
的值 例如沒有呼叫過requestFullscreen()
,按F11
全屏後該值仍然是null - 全屏和退出時都不會發出
fullscreenchange
事件 - 在按
F11
進入全屏時,會發出keydown
事件,而退出全屏時則不會發出該事件 F11
可以退出requestFullscreen()
的全屏狀態,但Esc
、exitFullscreen()
都不能退出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
如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。