3.6 Browser – useFullscreen
https://vueuse.org/useFullscreen
作用
响应式的Fullscreen API
。可以让特定的元素占满屏幕,就是全屏的效果。
官方示例
const el = ref<HTMLElement | null>(null)
const { isFullscreen, enter, exit, toggle } = useFullscreen(el)
<video ref='el'>
通过函数调用的方式,让video
可以实现全屏效果。
源码分析
https://github.com/vueuse/vueuse/blob/main/packages/core/useFullscreen/index.ts
源码中对多种浏览器进行了适配,这种适配的思路需要学习一下。
功能实现简单来说就两条:target.requestFullscreen
打开全屏,document.exitFullscreen
退出全屏。
const functionsMap: FunctionMap[] = [
[
'requestFullscreen',
'exitFullscreen',
'fullscreenElement',
'fullscreenEnabled',
'fullscreenchange',
'fullscreenerror',
],
// New WebKit
[
'webkitRequestFullscreen',
'webkitExitFullscreen',
'webkitFullscreenElement',
'webkitFullscreenEnabled',
'webkitfullscreenchange',
'webkitfullscreenerror',
],
// ......
]
export function useFullscreen(
target?: MaybeElementRef,
options: UseFullscreenOptions = {},
) {
const { document = defaultDocument, autoExit = false } = options
const targetRef = target || document?.querySelector('html')
const isFullscreen = ref(false)
// 取数组第一项定义的方法名
let map: FunctionMap = functionsMap[0]
const isSupported = useSupported(() => {
if (!document) {
return false
}
else {
for (const m of functionsMap) {
if (m[1] in document) {
map = m
return true
}
}
}
return false
})
// [
'requestFullscreen',
'exitFullscreen',
'fullscreenElement',
'fullscreenEnabled', // 这条被跳过了,通过留空的方式
'fullscreenchange',
'fullscreenerror', // 最后一条没有解构
// ],
const [REQUEST, EXIT, ELEMENT,, EVENT] = map
async function exit() {
if (!isSupported.value)
return
// 如果当前有全屏的元素 document.fullscreenElement,退出全屏模式,修改isFullscreen
if (document?.[ELEMENT])
await document[EXIT]()
isFullscreen.value = false
}
async function enter() {
if (!isSupported.value)
return
// 先尝试退出全屏
await exit()
const target = unrefElement(targetRef)
if (target) {
// target.requestFullscreen 请求全屏
await target[REQUEST]()
isFullscreen.value = true
}
}
// 切换
async function toggle() {
if (isFullscreen.value)
await exit()
else
await enter()
}
if (document) {
useEventListener(document, EVENT, () => {
isFullscreen.value = !!document?.[ELEMENT]
}, false)
}
if (autoExit)
tryOnScopeDispose(exit)
return {
isSupported,
isFullscreen,
enter,
exit,
toggle,
}
}