interface IScreenFullOptions{
document?:Document
autoEixt?:Boolean
}
const useScreenFull = (target:any,options:IScreenFullOptions)=>{
const {
document = window ? window.document : undefined,
autoEixt = false
} = options
const isFullSreen = ref(false)
//计算目标
const targetEl = computed(()=>unref(target) || document.querySelector('html'))
const requestMethods = [
'requestFullscreen',
'webkitRequestFullscreen', //Chrome、Safari、Opera
'webkitEnterFullscreen', //Android 的 X5 内核浏览器
'webkitEnterFullScreen', //Android 的 X5 内核浏览器
'webkitRequestFullScreen',
'mozRequestFullScreen', Firefox
'msRequestFullscreen', IE/Edge
]
const exitMethods = [
'exitFullscreen',
'webkitExitFullscreen',
'webkitExitFullScreen',
'webkitCancelFullScreen',
'mozCancelFullScreen', //Firefox
'msExitFullscreen', //IE/Edge
]
//是否支持全屏
const isFullSrceenEabledNames = [
'fullScreen',
'webkitIsFullScreen',
'webkitDisplayingFullscreen',
'mozFullScreen',
'msFullscreenElement',
]
//是否哪个元素处于全屏状态
const elementFullSreenNames = [
'fullscreenElement',
'webkitFullscreenElement',
'mozFullScreenElement',
'msFullscreenElement',
]
//监听事件
const eventHandlers = [
'fullscreenchange',
'webkitfullscreenchange',
'webkitendfullscreen',
'mozfullscreenchange',
'MSFullscreenChange',
]
const requestMethod = computed(()=>requestMethods.find((m)=>(m in document || (targetEl.value && m in targetEl.value ))))
const exitMethod = computed(()=>exitMethods.find((m)=>(m in document || (targetEl.value && m in targetEl.value ))))
//是否处于全屏状态
const isFullSrceenEabled = computed(()=>isFullSrceenEabledNames.find((m)=>(m in document || (targetEl.value && m in targetEl.value ))))
//返回现在处于全屏状态的是哪一个元素
const elementFull = computed(()=>elementFullSreenNames.find((m)=>(m in document || (targetEl.value && m in targetEl.value ))))
const isSuport = computed(()=>{
return (targetEl.value && document && requestMethod.value && exitMethod.value && isFullSrceenEabled.value && elementFull.value)
})
//是否有元素处于全屏状态
const isElementFull = ()=>{
if(document[isFullSrceenEabled.value] !== null)
{
return document[isFullSrceenEabled.value]
}else{
if(targetEl.value[isFullSrceenEabled.value]!== null)
{
return Boolean(targetEl.value[isFullSrceenEabled.value])
}
return false
}
}
//判断处于全屏状态的元素是否是当前元素
const isCurrentElementFull = ()=>{
if(document[elementFull.value]!==null){
return document[elementFull.value] === targetEl.value
}else{
return false
}
}
// 这是因为HTML5全屏API允许任何元素(而不仅仅是整个文档)进入全屏模式。这意味着开发者可以选择页面上的特定元素
const enterFullSreen = async()=>{
try {
//如果不支持或者正处于全屏状态就return
if(!isSuport.value || isFullSreen.value) return;
if(isElementFull) exitFullscreen()
if(requestMethod.value){
if(targetEl.value?.[requestMethod.value] !== null){
await targetEl.value[requestMethod.value]?.()
isFullSreen.value = true
}
}
} catch (error) {
console.error('进入全屏失败',error)
}
}
//退出全屏时使用document对象,主要是因为HTML5全屏API的设计。在HTML5中,全屏模式是由浏览器控制的,
//而document对象代表了整个文档,是与浏览器窗口交互的入口点。当需要退出全屏模式时,需要调用浏览器提供的全屏API,而这个API通常是挂载在document对象上的
//当进入全屏模式时,可能是某个特定元素(如视频、图像等)进入了全屏。但退出全屏时,需要告诉浏览器整个文档要退出全屏状态,而不是仅仅退出某个元素的全屏
const exitFullscreen = async()=>{
try {
if(!isSuport.value || !isFullSreen.value) return;
if(exitMethod.value){
if(document[exitMethod.value] !== null){
await document[exitMethod.value]?.()
}else{
if(targetEl.value?.[exitMethod.value] !== null){
await targetEl.value[exitMethod.value]?.()
}
isFullSreen.value = false
}
}
} catch (error) {
console.error('退出全屏失败',error)
}
}
const toggle = ()=>{
isFullSreen.value ? exitFullscreen() : enterFullSreen()
}
//对切换全屏状态进行监听
const handleCallBack = ()=>{
const isFullE = isElementFull()
if(!isFullE || (isFullE && isCurrentElementFull)){
isFullSreen.value = isFullE
}
}
//监听ext退出全屏
useEventListener(targetEl,eventHandlers,handleCallBack)
useEventListener(document,eventHandlers,handleCallBack)
if(getCurrentScope()){
//副作用消失的时候进行退出
if(autoEixt){
onScopeDispose(exitFullscreen)
}
}
return {
enterFullSreen,
exitFullscreen,
toggle,
isSuport,
isFullSreen
}
}
export default useScreenFull
vue实现全屏功能的hook
最新推荐文章于 2024-09-13 14:34:15 发布