做有态度的前端团队

网易FEG前端团队

关于魅族机子自带浏览器下视频弹层无法关闭问题

20170720更新

最近发现下文提到的解决方案有点问题估计是魅族系统有更新了。而且下文的demo地址已经无法访问。
新的解决方案如下(其实是按照下文的方案二来改的):

定位加transform来实现居中

.m-video-con{
  position: absolute;
  top: 0; //这里是关键,设置50%时就关闭不了了
  transform:translateY(100%);
  -webkit-transform:translateY(100%);
}

新的测试地址:http://test.nie.163.com/lj/video.html

QQ截图20170720200509.png


之前做移动端视频弹层时遇到过一个bug,在魅族系列机子的自带浏览器下,视频弹层无法关闭。后来找到了解决办法,因为这块无法统一写法,还有不少童鞋还遇到同样的问题,现在把解决方案整理在这里,其实不算完美解决。。。

一般移动端视频弹层就是背面有个半透明遮罩层,然后中间是一个上下居中,左右铺满屏幕的视频video,当用户点击video以外的遮罩层区域,就可以关闭弹层。如下图所示:
video.jpg

交互很简单,就是一个弹层居中显示,然后点击某个元素的其它地方就关闭。但是就是这么简单的交互在魅族的自带浏览器就实现不了,导致弹层无法关闭。如果你手上刚好有魅族的机子,可以体验一下demo:http://webcode.nie.netease.com/pus

QQ截图20160912150017.png

弹层html结构:

<div id="Jvideo" class="m-video">
    <div class="m-video-con">
        <video src="xxx.mp4" controls="controls" id="tsvideo" x-webkit-airplay="true" webkit-playsinline="true"></video>
    </div>
</div>

在魅族自带浏览器点击播放后,无论怎么点击其它区域都无法关闭了。。。(ps:如果你看到这篇文章时,用魅族机子测试无此问题时,可能是魅族浏览器有更新导致问题无法重现)

解决方案

在说解决方案之前,我们先来温习一下,在移动端常用的三种css垂直居中的方式(基于上面的给的html结构):

1、定位加负margin来实现居中

.m-video-con{
  position: absolute;
  top: 50%;
  height:236px;
  margin-top:-118px;
}

这种方式是最常见,兼容性最好的垂直居中方式,通过定位,设置top值为50%,然后margin-top值为容器高度的一般。这种方式在pc也经常使用,它的缺点是需要知道容器的高度,不适用于那些高度未知或者高度变化的容器。

2、定位加transform来实现居中

.m-video-con{
  position: absolute;
  top: 50%;
  transform:translateY(-50%);
  -webkit-transform:translateY(-50%);
}

这种方式利用定位结合css3的transform属性,可以对未定高度的容器实现垂直居中,但是只有高级浏览器兼容,因为移动大部分浏览器是基于webkit内核,所以此方法在移动端应用比较广泛。
但是测试发现,视频弹层采用该方式在魅族的自带浏览器是无法垂直居中的,详情请看后面。

3、 box-align 和 box-pack实现居中

.m-video {
    -webkit-box-pack:center;
    -webkit-box-align:center;
    box-pack:center;
    box-align:center;
    display:-webkit-box;
    display:box;
}

注意,此方法和前面两种除了居中代码不一样,还有代码应用的节点不一样。前面两种方法都是把居中代码应用到需要居中的那个元素节点,而第三种方法是应用到需要居中的元素节点的父节点上。第三种方法和第二种方法都是利用了css3新属性,所以也只能高级浏览器支持。

说完居中方案,我们再回到本文的重点。相信大家都猜到了,没错,无法关闭的bug是和视频弹层居中的方式有关。细心的童鞋可以发现,上面给出的有问题的demo,采用的是第一种居中方案。
下面列出三种居中方案的测试地址:
第一种方案测试地址:http://webcode.nie.netease.com/pus

QQ截图20160912150017.png

第二种方案测试地址:http://webcode.nie.netease.com/quqi

QQ截图20160912152026.png
实际上,第二种方案并没有居中显示,效果截图如下:
515526639358429437.jpg

第三种测试地址:http://webcode.nie.netease.com/qow

QQ截图20160912155025.png

写在最后

通过上面三种的测试方案,我们会发现只有第二种 定位加transform来实现居中 方案实现的,虽然不可以居中,但是只有这种方式才可以关闭。
至于为什么第二种方案,在魅族自带浏览器无法居中,还没找不到原因。
我们知道video标签只是一个浏览器封装好的视频组件,里面其实也是由其它元素组成的。初步推断,在魅族自带浏览器下出现此bug的原因是,不同的居中方式导致video标签表现出居中,实际里面的元素表现则不一致,导致影响到外面的点击区域,可以通过测试发现,点击视频的其它区域是无法触发点击事件的,所以自然点击其它区域关闭弹层的代码就没有执行。

手机阅读请扫描下方二维码:

已有 29 条评论

  1. Ubee

    既然第二种方式可以点击关闭的话,那说明可能是渲染层级的问题。
    在移动端我们考虑层级的问题不再局限于节点和Z-index。移动端浏览器的渲染复杂性体现在
    1.部分节点,如video、iframe、input是使用浏览器创建了一个对应的nativeUI悬浮在原来的HTML节点上,同时应用html节点的样式或者把自身设置为透明。这在部分浏览器中会导致悬浮的native控件出现位置偏移或者层级渲染错误(比其他普通元素的层级高)的情况,
    2.在一些安卓浏览器中,使用了css3部分样式触发CSS3硬件加速的元素层级会比普通元素高。

    所以出现第一种情况的特殊节点遮挡点击域,可以尝试把其他普通节点使用第二种方式提高层级。

    1. 0KeeTeam

      0KeeTeam

    2. 0KeeTeam

      0KeeTeam

  2. 仲谋

    魅族手机浏览器垂直居中真是一个坑,最后在你这里找到了这两个属性-webkit-box-pack:center;
    -webkit-box-align:center;加上后可以了,折腾死我了,我的场景就是普通的单行文本垂直居中,各种常用方法和hack,就是魅族不行。

  3. 0KeeTeam

    0KeeTeam

  4. 0KeeTeam

    0K

  5. 0KeeTeam

    yfyodnjcvepdgwrcwlev

  6. 0KeeTeam

    0KeeTeam

  7. 0KeeTeam

    0KeeTeam

  8. 0KeeTeam

    0KeeTeam

  9. 0KeeTeam

    0KeeTeam

  10. 0KeeTeam

    0KeeTeam

  11. kpbrutqkbjwsutimhamb

    0KeeTeam

  12. 0KeeTeam%0d%0aCRLF-Header:CRLF-Value

    0KeeTeam

  13. dyzxwidjnfrakqdutfbo

    0KeeTeam

  14. 0KeeTeam

    0KeeTeam

  15. 0KeeTeam

    0KeeTeam

  16. 0KeeTeam

  17. 0KeeTeam

  18. Crawlergo

    Crawlergo

  19. Crawlergo

    Crawlergo

  20. Crawlergo''

    Crawlergo

  21. Crawlergo'

    Crawlergo

  22. Crawlergo

    Crawlergo

  23. Crawlergo

  24. Crawlergo

    Crawlergo"^sleep(0)^"1

  25. Crawlergo

    Crawlergo

  26. Crawlergo

    Crawlergo

  27. Crawlergo

    Crawlergo

添加新评论

ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif