做有态度的前端团队

网易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标签表现出居中,实际里面的元素表现则不一致,导致影响到外面的点击区域,可以通过测试发现,点击视频的其它区域是无法触发点击事件的,所以自然点击其它区域关闭弹层的代码就没有执行。

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

已有 2 条评论

  1. Ubee

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

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

  2. 仲谋

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

添加新评论

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