Vue中实现全屏切换的完整过程和爬坑指导

前端老赵前端老赵 前端开发培训 616 0

Vue中实现全屏切换的完整过程和爬坑指导

在vue中,有时需要用到将页面设置为全屏显示,一般是在页面中设置一个按钮点击来实现,然后ESC键退出全屏,但这里面有很大的坑需要填


我们先把实现全屏的代码贴一下:

//id_selector指的是要全屏的dom的id
setFullScreen(id_selector) {
      var el = document.getElementById(id_selector);
      var isFullscreen =
        document.fullScreen ||
        document.mozFullScreen ||
        document.webkitIsFullScreen;
      if (!isFullscreen) {
        //进入全屏,多重短路表达式
        (el.requestFullscreen && el.requestFullscreen()) ||
          (el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
          (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) ||
          (el.msRequestFullscreen && el.msRequestFullscreen());
      } else {
        //退出全屏,三目运算符
        document.exitFullscreen
          ? document.exitFullscreen()
          : document.mozCancelFullScreen
          ? document.mozCancelFullScreen()
          : document.webkitExitFullscreen
          ? document.webkitExitFullscreen()
          : "";
      }
    },
 
 //按钮点击切换全屏事件
 toggle(){
     this.setFullScreen('container');
 }


以上可以实现全屏的切换,到这是没有问题的。


但是如果我们需要在切换全屏同时,改变data中的某个值如full_screen,通过 full_screen 来决定是不是显示一些额外的元素,那我们就要判断如何把这个full_screen的值进行改变,对吧? 那我们看有哪几种场景可以改变这个值呢?


1.toggle方法里直接更改

toggle(){
     this.setFullScreen('container');
     this.full_screen = !this.full_screen;
 }

这样实现乍一看是可以的,按钮的点击是可以改变full_screen的值,但是按下ESC退出全屏时,这个方法就不会被触发到了。


2.那在mouted中再添加监听ESC键的按下事件,来处理退出全屏不就可以了?

mounted() {
//监听键盘按键事件
let self = this;
this.$nextTick(function () {
	document.addEventListener('keyup', function (e) {
	if (e.keyCode == 27) {
		self.full_screen=false;
	}
	})
})
},

貌似代码上逻辑没有问题,但是坑出现了! 在全屏模式下,ESC可以退出全屏,但是无法监听到ESC的按下事件!这是什么鬼!


3.那我们只能再换个策略了,全屏和退出全屏时,window的大小改变了,那我们监听resize事件看看吧!

let self = this;
window.onresize = function() {
      var isFull =
            document.mozFullScreen ||
            document.fullScreen ||
            //谷歌浏览器及Webkit内核浏览器
            document.webkitIsFullScreen ||
            document.webkitRequestFullScreen ||
            document.mozRequestFullScreen ||
            document.msFullscreenEnabled;
          if (isFull === undefined) {
            isFull = false;
          }
          console.log('改变full_screen',isFull);
          if (!isFull) {
            self.full_screen= false;
          } else {
            self.full_screen= true;
          }
    };


代码逻辑上看似还是没有问题,但是实际运行发现,full_screen并没有按预期的进行变化!

查看控制台,你会发现,在点击全屏时,

改变full_screen:true
改变full_screen:false

竟然运行了两次,还一次true一次false?


网上一查,原来在全屏时,onResize事件是会运行两次的。。。一次被计算为全屏true,下一次被计算为全屏false。


4.那我们就必须用setTimeout和计数来消除这个偏差了!


代码如下:

    window.firstFire = null;
    window.onresize = function() {
      if (window.firstFire === null) {
        window.firstFire = setTimeout(() => {
          window.firstFire = null;
          var isFull =
            document.mozFullScreen ||
            document.fullScreen ||
            //谷歌浏览器及Webkit内核浏览器
            document.webkitIsFullScreen ||
            document.webkitRequestFullScreen ||
            document.mozRequestFullScreen ||
            document.msFullscreenEnabled;
          if (isFull === undefined) {
            isFull = false;
          }
          if (!isFull) {
            self.fullscreen = false;
          } else {
            self.fullscreen = true;
          }
        }, 100);
      }
    };


到这,我们的功能才算是全部实现,想不到一个简单的全屏操作,能有这么多坑!


以下是实现全屏切换的完整代码:

mounted() {
    window.firstFire = null;
    window.onresize = function() {
      if (window.firstFire === null) {
        window.firstFire = setTimeout(() => {
          window.firstFire = null;
          var isFull =
            document.mozFullScreen ||
            document.fullScreen ||
            //谷歌浏览器及Webkit内核浏览器
            document.webkitIsFullScreen ||
            document.webkitRequestFullScreen ||
            document.mozRequestFullScreen ||
            document.msFullscreenEnabled;
          if (isFull === undefined) {
            isFull = false;
          }
          if (!isFull) {
            self.fullscreen = false;
          } else {
            self.fullscreen = true;
          }
        }, 100);
      }
    };
},

methods:{

//id_selector指的是要全屏的dom的id
setFullScreen(id_selector) {
      var el = document.getElementById(id_selector);
      var isFullscreen =
        document.fullScreen ||
        document.mozFullScreen ||
        document.webkitIsFullScreen;
      if (!isFullscreen) {
        //进入全屏,多重短路表达式
        (el.requestFullscreen && el.requestFullscreen()) ||
          (el.mozRequestFullScreen && el.mozRequestFullScreen()) ||
          (el.webkitRequestFullscreen && el.webkitRequestFullscreen()) ||
          (el.msRequestFullscreen && el.msRequestFullscreen());
      } else {
        //退出全屏,三目运算符
        document.exitFullscreen
          ? document.exitFullscreen()
          : document.mozCancelFullScreen
          ? document.mozCancelFullScreen()
          : document.webkitExitFullscreen
          ? document.webkitExitFullscreen()
          : "";
      }
    },


 //按钮点击切换全屏事件
 toggle(){
     this.setFullScreen('container');
 }

}




本文系前端老赵独家发表,未经许可,不得转载。

喜欢0发布评论

评论列表

发表评论

  • 昵称(必填)
  • 邮箱
  • 网址