本人平时刷视频比较多. 视频类的脚本也多. 不过总有体验不是很好的地方. 于是打算自己撸. 在处理网页全屏时.遇到一些问题. 困扰我很久了.现在贴出来给各位大佬们看看.能不能指点一下.
先贴代码:
fullscreen: (() => {
const CLASS = "uweb-fullscreen";
let parents = []; // 缓存追加过的元素
css(`.${CLASS} {
margin: 0 !important;
padding: 0 !important;
inset: 0 !important;
width: 100vw !important;
min-width: 0vw !important;
max-width: 100vw !important;
height: 100vh !important;
min-height: 0vh !important;
max-height: 100vh !important;
position: fixed !important;
background: #000 !important;
transform: none !important;
z-index: 2147483646 !important;
object-fit: contain !important; }`);
const _toggle = (element) => {
if (parents.length) {
// 如果已经追加过了. 就代表删除
parents.forEach((el) => el.classList.remove(CLASS));
parents = [];
} else {
// 关于这里为什么用element.parentElement.parentElement;
// 因为主流视频的进度条都是video元素的祖父元素平级. 这是为了全屏时不遮挡进度条
// 但是这样有一个问题.就是如果video的祖父元素的宽高比较特殊,
// 那么会导致视频不能完整显示.进度条仍然有可能被遮挡. 不出现在视窗
// 我在想.或许可以通过css另外写一些样式解决.可是能力有限.不太懂css,所以不确定
// 原本是打算通过算法找到进度条.比如通配特征. 类名. 属性等.这样开销太大了.
// 在混杂进度条在底部的特征.仍然感觉复杂.
// 也想过通过video的祖父元素 .遍历他.让他所有子元素提升z-index .不过这样太蠢了. // 也想过比较 offsetWidth 和 offsetHeight,但是适配还是有问题.
element = element.parentElement.parentElement;
while (element && element !== document.body) {
parents.push(element);
element.classList.add(CLASS);
element = element.parentElement;
}
}
};
// 顶层收到消息, 找到这个iframe 开始走切换流程
window.top === window && imsg.on(CLASS, (src) => _toggle(document.querySelector(`iframe[src="${src}"], iframe[src*="m3u8"]`)));
return {
// 如果是iframes 发起的调用,那么通知顶层处理,附带链接.方便查找.
web: (el = videoController.player) => (_toggle(el), window !== window.top && imsg.toParent(CLASS, location.href)),
full: (el = videoController.player) => (document.fullscreenElement ? document.exitFullscreen() : el.parentElement.requestFullscreen()),
};
})(),
简单的写了几句注释. 可惜页面看上去格式有点乱. 在贴一下imsg的代码:
export const imsg = {
send(target, channel, data) {
if (target?.postMessage) target.postMessage({ __iframeMsg__: true, channel, data }, "*");
},
toParent(channel, data = {}) {
this.send(window.parent, channel, data);
},
reply(event, channel, data = {}) {
if (event.source && event.source.postMessage) this.send(event.source, channel, data);
},
on(channel, callback) {
window.addEventListener("message", (event) => {
const msg = event.data;
if (msg?.__iframeMsg__ && msg.channel === channel) callback(msg.data, event);
});
},
};
核心问题都写在注释里了. 文档写的少.大家凑合看吧. 解决不了问题就只能抛出去. 坐等大佬!!!
`