在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'); } }
本文系前端老赵独家发表,未经许可,不得转载。
评论列表
发表评论