Js 網頁全屏(vue)-2020-08-26-親測兼容 F11、ESC的全屏操作


Js 網頁全屏(vue)

效果描述

以下邏輯均正常

點擊按鈕全屏、點擊按鈕退出全屏、再點擊按鈕全屏

點擊按鈕全屏,F11 / ESC 退出全屏,點擊按鈕全屏

F11 進入全屏,點擊按鈕退出全屏

不同頁面操作全屏,切換全屏均能精准的控制按鈕顯示的是全屏 / 縮放

申明

  • 本 demo 默認狀態是全屏(刷新網頁也會退出全屏,切換頁面不會)

  • 只考慮網頁全屏,不考慮網頁單個元素全屏

    • 項目中有彈窗全屏等,可能會有兼容bug,暫時沒有去試驗,不知道如何
  • 代碼里結合了 vuex,安裝使用請參考:VueX(Vue狀態管理模式)

瀏覽器兼容效果:

(僅用公司電腦上有的幾個瀏覽器測試了一遍)

  • 谷歌瀏覽器、IE11、Edge火狐、360安全瀏覽器 均能正常支持本博客的全屏方法以及全屏css

本博客起因

還是想叨叨一下為什么百度這么方便還是會有這么一篇博客,畢竟是惡心過來的

(這個方案是我寫了好幾個版本才得出的)

  • 最主要的還是自己看着 bug不爽

一:全屏API各瀏覽器支持不同(主要講的是里面的方法,谷歌瀏覽器里部分兼容...)

  • 我要判斷全屏木的辦法,一會兒靈一會兒不靈的

二:無法監聽 ESC、F11 退出全屏的事件(即使我已經監聽了這兩個案件事件,在退出全屏的時候,它們依舊不能被監聽到)

  • 我自己記錄的全屏狀態被這兩個案件搞混亂了

解決方案

參考博客中有提到:

  • 注意:要在用戶授權全屏后才能獲取全屏的元素(但我的瀏覽器好像沒有授權這么個操作,所以不管它)

解決思路

主要在 vuex 中處理全屏狀態變量 fullscreen 與真正操作瀏覽器全屏退出全屏

  • vuex 中的變量很多地方都可以獲取到
  • 定義一個全屏處理方法,根據當前網頁是否有全屏元素來進入或者退出全屏

在 app.vue 全局里監聽 F11 與全屏改變事件

  • 等於把 F11 的進入全屏改成了自己的進入全屏
  • ESC退出全屏監聽不到,也就不監聽它的按鍵了
  • 通過全屏事件監聽來改變全屏狀態變量 fullscreen 的值(在 ESC、F11 退出全屏的時候也會觸發)

在 xx.vue 中給按鈕增加全屏、縮放(退出全屏)功能

  • 調用 vuex 中的處理全屏方法

(也可以寫一個 lib 通用函數,將變量與函數都封裝進入,然后在合適的地方調用,全屏事件監聽放在什么位置暫時沒有想清楚(主要是不同頁面切換該如何管理這個監聽事件))

代碼實現

src\store\index.js(vuex)

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    // 全屏變量,標識當前是否為全屏狀態
    fullscreen: false,
    element: document.documentElement
  },
  mutations: {
    // 改變全屏狀態變量
    changeFullscreenVar(state) {
      state.fullscreen = !state.fullscreen
    },
    // 進入全屏
    lanchFullscreen(state) {
      var element = state.element
      if(element.requestFullscreen) {
        element.requestFullscreen()
      } else if(element.mozRequestFullScreen) {
        element.mozRequestFullScreen()
      } else if(element.msRequestFullscreen) {
        element.msRequestFullscreen()
      } else if(element.webkitRequestFullscreen) {
        element.webkitRequestFullScreen()
      }
    },
    // 退出全屏
    exitFullscreen(state) {
      if(document.exitFullscreen) {
        document.exitFullscreen()
      } else if(document.mozCancelFullScreen) {
        document.mozCancelFullScreen()
      } else if(document.msExitFullscreen) {
        document.msExiFullscreen()
      } else if(document.webkitCancelFullScreen) {
        document.webkitCancelFullScreen()
      }
    },
    // 暴露給外界的處理方法,調用這個方法,自行判斷是要全屏還是退出全屏
    handleFullScreen(state) {
      // 注意:要在用戶授權全屏后才能獲取全屏的元素,否則 fullscreenEle為null
      var fullscreenEle = fullscreenEle = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
      console.log(fullscreenEle, '全屏元素...')
      if(fullscreenEle) {
        console.log('exitFullscreen..')
        this.commit('exitFullscreen')
      } else {
        console.log('lanchFullscreen..')
        this.commit('lanchFullscreen')
      }
    }
  },
  actions: {
      
  },
  modules: {
      
  }
})

src\App.vue

<template>
    <router-view />
</template>

<script>
export default {
  name: 'App',
  components: {
      
  },
  mounted() {
    window.addEventListener('keydown', this.myKeyEvent)
    
    if(document.exitFullscreen) {
      document.addEventListener('fullscreenchange', this.changeFullscreenVar)
    } else if(document.mozCancelFullScreen) {
      document.addEventListener('mozfullscreenchange', this.changeFullscreenVar)
    } else if(document.msExitFullscreen) {
      document.addEventListener('MSFullscreenChange', this.changeFullscreenVar)
    } else if(document.webkitCancelFullScreen) {
      document.addEventListener('webkitfullscreenchange', this.changeFullscreenVar)
    }
  },
  methods: {
    myKeyEvent(e) {
      let key = e.keyCode
      if (key === 122) {
        console.log('F11')
        // 阻止默認的鍵盤事件
        event.returnValue = false
        this.$store.commit('handleFullScreen')
      }
    },
    changeFullscreenVar(){
      this.$store.commit('changeFullscreenVar')
    },
    fullScreenChange(event) {
      console.log(event, 'fullScreenChange event')
      // 判斷一下變量是不是全屏,是全屏則代表 F11、ESC 退出了全屏,需要變量更正過來
      if(this.$store.state.btnFullScreen && this.$store.state.fullscreen) {
        this.$store.commit('changeFullScreenVariable')
      }
    },
  },
  beforeDestroy() {
    window.removeEventListener('keydown', this.myKeyEvent)
    if(document.exitFullscreen) {
      document.removeEventListener('fullscreenchange', this.changeFullscreenVar)
    } else if(document.mozCancelFullScreen) {
      document.removeEventListener('mozfullscreenchange', this.changeFullscreenVar)
    } else if(document.msExitFullscreen) {
      document.removeEventListener('MSFullscreenChange', this.changeFullscreenVar)
    } else if(document.webkitCancelFullScreen) {
      document.removeEventListener('webkitfullscreenchange', this.changeFullscreenVar)
    }
  }
}
</script>

src\views\xx.vue

<template>
      <div v-if="!$store.state.fullscreen" class="btn cursorPointer" @click="clickTopBtn('handleFullScreen')">
        <img src="./../assets/images/quanping.png" alt="">
        全屏
      </div>
      <div v-else class="btn cursorPointer" @click="clickTopBtn('handleFullScreen')">
        <img src="./../assets/images/suofang.png" alt="">
        縮放
      </div>
</template>


<script>
export default {
  methods: {
    clickTopBtn(func) {
        this.$store.commit('handleFullScreen')
    }
  }
}
</script>

<style>
/*重在功能邏輯代碼,樣式自己寫*/
</style>

全屏css樣式

/* 多瀏覽器兼容性寫法(親測有效) */

/* Chrome, Safari, Opera 寫法 */
:-webkit-full-screen { }

/* Firefox 寫法 */
:-moz-full-screen { }

/* IE/Edge 寫法 */
:-ms-fullscreen { }

/* 標准寫法 */
:fullscreen { }


/* 也可以通過區分全屏元素 css選擇器、瀏覽器全屏樣式 */
#fullscreenEle:fullscreen { }

在全屏狀態需要改變樣式的地方根據自己的項目寫就好了

/* :fullscreen */
:fullscreen #centerInfo,
:fullscreen #rightContent{
  display: none;
}
:fullscreen .menuItem:not(:nth-last-child(1)) {
  margin-right: 20px;
}
:fullscreen #navMenu{
  width: unset;
  border-radius: 8px;
  left: 10px;
  top: 10px;
}


/* :-webkit-full-screen  */
:-webkit-full-screen #centerInfo,
:-webkit-full-screen #rightContent{
  display: none;
}

:-webkit-full-screen .menuItem:not(:nth-last-child(1)) {
  margin-right: 20px;
}

:-webkit-full-screen #navMenu{
  width: unset;
  border-radius: 8px;
  left: 10px;
  top: 10px;
}


/* :-moz-full-screen */
:-moz-full-screen #centerInfo,
:-moz-full-screen #rightContent{
  display: none;
}

:-moz-full-screen .menuItem:not(:nth-last-child(1)) {
  margin-right: 20px;
}

:-moz-full-screen #navMenu{
  width: unset;
  border-radius: 8px;
  left: 10px;
  top: 10px;
}


/* :-ms-fullscreen */
:-ms-fullscreen #centerInfo,
:-ms-fullscreen #rightContent{
  display: none;
}

:-ms-fullscreen .menuItem:not(:nth-last-child(1)) {
  margin-right: 20px;
}

:-ms-fullscreen #navMenu{
  /* IE 不能用 unset,案例中改成 auto 也行 */
  width: auto;
  border-radius: 8px;
  left: 10px;
  top: 10px;
}

特別鳴謝

能得出這套個人看似完美的方案,多虧了這篇博客:HTML5 API詳解(1):fullscreen全屏模式

非常感謝~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM