vue实现全屏功能的hook

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值