原生 FullScreen API
Element.requestFullscreen()
用于将特定元素打开全屏。使用方式是先获取HTML Element元素,然后调用其 requestFullscreen
方法:
const buttomElem = document.getElementById('myButton');
buttomElem.addEventListener('click', function() {const videoElem = document.getElementById("myVideo");// 打开全屏videoElem.requestFullscreen();
}, false);
注意:打开全屏只能通过用户操作触发,比如click事件。如果在一开始加载页面的时候调用 requestFullscreen
方法并不能打开全屏,且会在控制台中看到报错。
document.exitFullscreen()
用于退出全屏模式,与 requestFullscreen
不同,该方法挂载在document中:
const closeElem = document.getElementById('close');
closeElem.addEventListener('click', function() {// 退出全屏document.exitFullscreen();
}, false);
document.fullscreenElement
该属性表示当前全屏模式下的Element元素。如果这个值为null,则表示不处于全屏模式。使用这个属性可以判断当前页面是否处于全屏模式:
// 切换全屏和非全屏模式的按钮
const toggleElem = document.getElementById('toggle');
toggleElem.addEventListener('click', function() {// 判断是否是全屏模式if (document.fullscreenElement) {// 退出全屏document.exitFullscreen(); } else {const videoElem = document.getElementById("myVideo");// 打开全屏 videoElem.requestFullscreen(); }
}, false);
document.fullscreenEnabled
该属性表示当前浏览器是否是否支持全屏模式。
const buttomElem = document.getElementById('myButton');
buttomElem.addEventListener('click', function() {if (document.fullscreenEnabled) {alert('不支持全屏');return;} // 这里放打开全屏的操作代码
}, false);
fullscreenchange事件
document
对象 和 Element
对象均可监听 fullscreenchange
事件。用于监听全屏模式的变化
document.addEventListener('fullscreenchange', function () {if (document.fullscreenElement) {console.log(`当前为打开全屏模式`);} else {console.log('当前为退出全屏模式');}
});
Fullscreen API 的兼容问题
不同浏览器对Fullscreen的API使用方式并不一样。webkit、Firefox和IE需要添加给Fullscrren API添加特殊前缀才能使用,也有一些API名称不一样了,请看下面的表格:
标准 | webkit | Firefox | IE | |
---|---|---|---|---|
打开全屏 | requestFullscreen | webkitRequestFullscreen | mozRequestFullScreen | msRequestFullscreen |
退出全屏 | exitFullscreen | webkitExitFullscreen | mozCancelFullScreen | msExitFullscreen |
全屏元素 | fullscreenElement | webkitFullscreenElement | mozFullScreenElement | msFullscreenElement |
是否支持全屏 | fullscreenEnabled | webkitFullscreenEnabled | mozFullScreenEnabled | msFullscreenEnabled |
全屏变化事件 | fullscreenchange | webkitfullscreenchange | mozfullscreenchange | MSFullscreenChange |
全屏报错事件 | fullscreenerror | webkitfullscreenerror | mozfullscreenerror | MSFullscreenError |
如果要兼容所有的浏览器,需要判断不同的浏览器环境并使用对应的API。例如下面是一个兼容 requestFullscreen
的例子:
requestFullscreen.compatibility.js:
function requestFullscreen(element) {if (element.requestFullscreen) {element.requestFullscreen();} else if (element.mozRequestFullScreen) {element.mozRequestFullScreen();} else if (element.webkitRequestFullScreen) {element.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);}
}
exitFullscreen
、fullscreenElement
等其余的Fullscreen API也要做类似的兼容。这种兼容代码自己来写真的十分麻烦,这个时候可以求助于一个npm包:screenfull。
screenfull
screenfull的API兼容了所有浏览器的调用方式,且API使用起来更加简洁。上面requestFullscreen.compatibility.js的例子,用了screenfull后只需寥寥几行代码:
import screenfull from 'screenfull';
function requestFullscreen(element) {screenfull.request(element);
}
下面是原生 Fullscreen API与 screenfull
API的对应关系:
import screenfull from 'screenfull';
// 打开全屏
function requestFullscreen(element) {screenfull.request(element);
}
// 退出全屏
function exitFullscreen() {screenfull.exit();
}
// 获取全屏模式下的元素
function fullscreenElement() {return screenfull.element;
}
// 获取浏览器是否支持全屏模式
function fullscreenEnabled() {return screenfull.isEnabled;
}
// 监听全屏事件
function onfullscreenchange(callback) {screenfull.on('change', () => {// screenfull.isFullscreen用于判断当前是否全屏callback(screenfull.isFullscreen);});
}
IOS视频全屏
我们先看看原生 Fullscreen API 的兼容表:
嗯,挺多绿的。但是细心观察的话会发现有个“刺头”:
对,我们亲爱的IOS系统并不支持原生 Fullscreen API。IOS只能对video元素全屏,其他HTML元素都不能全屏,而且IOS的全屏API是独有的API:
VideoElement.webkitEnterFullscreen
:打开video全屏VideoElement.webkitDisplayingFullscreen
:判断是否video的全屏模式
打开IOS视频全屏
VideoElement.webkitEnterFullscreen
接口可以打开 Video Element 元素的全屏:
const buttomElem = document.getElementById('myButton');
buttomElem.addEventListener('click', function() {const videoDom = document.getElementById('videoDom');if (videoDom?.webkitEnterFullscreen) {// 打开全屏videoDom.webkitEnterFullscreen();}
}, false);
全屏后的视频是IOS的原生视频UI,这些原生UI并不能控制,所以也就没有关闭全屏之类的API。
IOS全屏变化事件
笔者找了一轮都没找到IOS视频全屏变化事件,最终使用了定时器的方法模拟了一个全屏事件:
let cleanVideoTimer = null;
function onFullScreenChange() {cleanVideoTimer = setInterval(() => {const videoDom = document.getElementById('videoDom');if (videoDom?.webkitDisplayingFullscreen) {// 视频元素处于全屏模式} else {// 视频元素退出全屏}}, 1000);
}
function offFullScreenChange() {clearInterval(cleanVideoTimer);
}
IOS假全屏
IOS用的是原生的视频UI,因此不能自定义视频UI控件。解决方案是使用假全屏方案,即通过CSS的形式使video元素占满屏幕。
function openFullScreen() {const videoDom = document.getElementById('video-dom');// 用CSS撑满整个屏幕videoDom.style.position = 'fixed';videoDom.style.top = '0px';videoDom.style.right = '0px';videoDom.style.bottom = '0px';videoDom.style.left = '0px';videoDom.style.zIndex = '999';
}
function closeFullScreen() {const videoDom = document.getElementById('video-dom');videoDom.style.position = 'static';videoDom.style.top = 'auto';videoDom.style.right = 'auto';videoDom.style.bottom = 'auto';videoDom.style.left = 'auto';videoDom.style.zIndex = '1';
}
此时全屏后的video元素是可控的HTML元素,想怎么自定义就怎么自定义。
B站的H5版本就是使用假全屏,但是假全屏不能做到真正全屏,浏览器的导航栏依然会显示:
最后
最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。
有需要的小伙伴,可以点击下方卡片领取,无偿分享