11月01, 2018

Chrome69 Video 全屏播放时css伪类规则改变引发的bug

前段时间做了个需求,h5点击按钮全屏播放视频,不播放的时候不现实video界面。 先把video加上display:none, js触发video全屏播放就可以显示然后播放,退出全屏暂停播放,隐藏video。 chrome和safari都支持webkitFullScreen 这个api,所以这个功能都安卓和ios手机上没问题。搞定,美滋滋。 后来测试跟我说pc chrome上播放不了,全屏了,视频画面没有,有声音,控制台无报错,手机浏览器没问题(测试的电脑是chrome 69)

在线demo可以戳一下这里:codePen例子

看了很久发现是chrome 69的新特性,具体情况如下:

chrome 全屏播放的时候 元素会有对应的默认伪类 video 的父元素和祖先元素 都有伪类

:-webkit-full-screen-ancestor:not(iframe) {
    z-index: auto;
    position: static;
    opacity: 1;
    transform: none;
    filter: none;
    perspective: none;
    transform-style: flat;
    will-change: auto;
    -webkit-mask: none !important;
    transition: none !important;
}

video的元素 有伪类

video:-webkit-full-screen, 
audio:-webkit-full-screen {
    background-color: transparent;
    position: relative;
    left: 0px;
    top: 0px;
    min-width: 0px;
    max-width: none;
    min-height: 0px;
    max-height: none;
    width: 100%;
    height: 100%;
    display: block;/* 这个是重点*/
    transform: none;
    margin: 0px !important;
    flex: 1 1 0% !important;
}

重点来了: 这个伪类的优先级比行内样式的优先级高 而且无法重置这些属性,!important也不行,也就是说你无法更改这些全屏播放的样式。


chrome69更改了全屏元素默认伪类的匹配规则 所有的全屏元素会匹配如下伪类规则

:not(:root):-webkit-full-screen {
    object-fit: contain;
    position: fixed !important;
    top: 0px !important;
    right: 0px !important;
    bottom: 0px !important;
    left: 0px !important;
    box-sizing: border-box !important;
    min-width: 0px !important;
    max-width: none !important;
    min-height: 0px !important;
    max-height: none !important;
    width: 100% !important;
    height: 100% !important;
    transform: none !important;
    margin: 0px !important;
}

这些属性依然是修改无效的。 可以发现,这里面没有了 display:block规则。

  • 我之前按照在chrome68下的规则,给video 加上属性display:none,点击按钮时候,全屏播放,这个属性就会失效。因为viedo元素全屏播放时的伪类里有display:block规则,这个优先级更高。这个时候视频就可以看见了。
  • 当我在chrome69下运行的时候,全屏播放时的伪类没有 display:block规则,所以我的视频依然看不见,导致了这个bug。
  • 解决:播放的时候利用伪类直接给video动态加个显示的属性,这样chrome69可以用,chrome68以下不影响。 加一段css即可解决:
    video:-webkit-full-screen{
          display:block !important;
    }
    

估计这个问题是webkit遗留下来的。因为ios上和安卓上表现都一样,现在谷歌有了独立的内核blink,安卓逐渐会有这个新特性,ios短时间内这个不影响。

但是过段时间,这个新特性在手机上都有了,还是按照最新的来吧。

这应该是chrome 69的 新feature吧,不能算bug。这个问题刚开始还真的吓我一跳,还好。

记录之。

补充一下: safari 和 chrome仍然只支持带webkit前缀的全屏属性和函数,事件,暂不支持不带全屏的, firefox浏览器的兼容性请参考最下面的链接。 具体如下:

//监听全屏进入和退出
document.addEventListener('webkitfullscreenchange', function(){
    if(document.webkitFullscreenElement == null){
     //退出全屏
    }
});

//申请全屏
var video= document.getElementById('video');
video.webkitRequestFullscreen();

兼容性: 安卓和ios上可以安全使用 chrome和safari可以安全使用 火狐和ie 不建议使用

参考: can i use 兼容性查询 MDN - Fullscreen_API Chrome Fullscreen

本文链接:http://www.hijs.cc/post/buglist_3.html

-- EOF --

Comments