HTML5全屏模式下隐藏默认视频控制栏

来源:互联网 发布:青少年法制网络大赛 编辑:程序博客网 时间:2024/05/16 10:08

HTML5 在全屏模式下隐藏默认视频控制栏

原文 Hiding Native HTML5 Video Controls in Full-Screen Mode

前言

 如果你曾经使用过HTML5的video,那么你肯定有想过为什么你仅仅向DOM添加了一个 <video> 标签却会多出了一堆的播放控制按钮

播放控制栏

浏览器以video标签子DOM的形式添加到渲染的文档中。这些播放控制元素也是DOM的一部分,但你并不能在主DOM树上看到他们,你只能看到他们被渲染在页面中

HTML 视频在全屏模式下控制栏的问题

 当我最近在做自定义HTML5视频播放框架的时候,遇到了很多设计师和开发者都遇到的一个问题,当视频进入全屏模式的时候,显示的是浏览器默认的播放控制栏而不是自定义的控制栏。跟别人一样,我在网上搜索但并没有找到相关的资料。

F12查看了开发者工具之后,我们可以发现:

  1. 默认的控制栏还在。把video元素的controls属性设置为false,在非全屏模式下控制栏确实是隐藏的,但是当我们进入全屏模式的时候,控制栏又出现了,这是为什么呢?

  2. 在全屏模式下自定义的控制栏被隐藏在视频的下面。在开发者工具中检查自定义的控制栏可以发现被隐藏的原因是控制栏应用了用户代理的样式表(the user agernt’s style sheet),而在这个样式表中有一个奇怪的z-index值,这是必须要注意的。

奇怪的z-index值

那么如何使得自定义控制栏在全屏模式下得到显示呢?
其实思路很简单,就是覆盖用户代理样式表。平时写样式表就是用来覆盖用户代理样式表的。但很重要的一点是,怎么隐藏浏览器插入的而不能在默认DOM树上发现的元素。

需要注意的是这篇文章所提到的技术仅仅在支持影子DOM(Shadow DOM)的浏览器中隐藏全屏模式下的控制栏。

影子DOM速览

 什么是影子DOM?影子DOM就是浏览器创建的在DOM子树。简单来说,它是一系列的DOM元素,跟熟悉的<div><span>一样,只不过影子DOM是浏览器添加的文档片段(document fragment)并且能够像DOM树一样在页面中得到渲染。下面引用James Edwards的话简要概括一下影子DOM的作用

影子DOM通过创建文档片段的形式高效地封装内容,影子DOM的内容是特殊的文档,会通过合并到主文档的方式来创建所有被渲染的内容。
实际上一些浏览器已经通过影子DOM的方式来渲染浏览器的插件

到现在了解到了添加到<video>标签的控制栏是浏览器创建的影子DOM的一部分,以及影子DOM的相关知识,接下来就会接触到如何隐藏默认的视频控制栏。

隐藏默认的视频控制栏

 现在需要重写影子DOM里控制栏的样式,然而在常规的CSS选择器不能获取影子DOM的情况下怎么实现呢?
Dimitri Glazkov的文章指出,有一个简单的伪属性可以允许影子DOM子树的任意伪元素和子树的元素联系起来。也就是说影子DOM子树中的一些元素可以通过与它们关联的伪元素来获取进而重写它们的样式。
但我们怎么确定我们需要重写样式的的影子DOM元素和哪个伪元素关联呢?我们或多或少知道像范围输入这样的控件在webkit浏览器中我们可以通过伪元素来重写它的指针样式,如

::-webkit-slider-thumb

FireFox同样提供了两个伪元素来重写样式

::-moz-range-track

::-moz-range-thumb

但其他更加少见的和影子DOM相关联的伪元素呢?又有什么伪元素和其他的影子DOM元素关联?Chrome的开发者工具可以帮助我们来找到他们。

确定伪元素和影子DOM元素的关联

 Chrome开发者工具有一个很好的特性就是你可以在Elements选项卡中检查影子DOM子树,就如同你检查普通的DOM树一样,所有想要做的东西都可一通过这个特性完美解决:

  1. 进入开发者模式按F1进入设置
  2. 在Preferences选项卡中的Elements中把Show user agent shadow DOM前的复选框勾上(并没有找到原文所说的Genral所以按照网上的其他文章重写了这个步骤)
  3. 重启开发者工具

现在我们就可以看到<video>下的影子DOM

检查video下的影子DOM

然后就像检查其他HTML元素一样你可以轻易的看到影子DOM元素和伪元素的关联关系。

所以为了得到视频控制栏,通过开发者工具我们可以知道它的伪元素为::-webkit-media-controls,通过名字我们就已经知道这是和视频控制栏相关联的标签。然后我们可以通过设置display:none !important来将它隐藏,完整的代码是

::-webkit-media-controls{    display:none !important;}

但需要记住的是子树中跟控制栏相关的伪元素是跟最外层的<div>相关联的,也就是说如果你在页面中有一个<audio>标签,那么也会同时隐藏<audio>的控制栏。
所以如果你不想隐藏所有的默认控制栏,你需要指定要隐藏哪一种类的控制栏,例如跟<video>标签相关的或者跟某一个id相关的等。如

video::-webkit-media-controls{    display:none !important;}

这样就能控制只隐藏视频的控制栏。这样的写法是将整个控制栏都隐藏掉,我们也可以分部分隐藏如

video::-webkit-media-controls-enclosure{    display:none !important;}

当我们将display属性设置为none后,无论是普通模式还是全屏模式都能隐藏掉控制栏了。

显示自定义的视屏控制栏

 至于我们的自定义控制栏,即使我们已经隐藏了默认的控制栏,但是我们的自定义控制栏还是没有显示出来,因为用户代理样式样式表中全屏模式下的z-index值如下图所示:

z-index

并不了解为什么开发者会选择这样一个特殊的数值,可能因为浏览器的开发者使用32位有符号整数来表示z-index值,而2147483647是最大值,为了确保自定义控制栏的可见性,你必须吧z-index值设置大于或等于该值。

.custom-video-controls{    z-index:217483647;}

总结

 为了在全屏模式下隐藏默认的控制栏并显示自定义控制栏,浏览器提供了影子DOM给开发者使用,使用步骤如下:

1.确认影子DOM元素和伪元素的关联关系,然后将其display属性设置为none
2.将自定义控制栏的z-index设置为32为有符号整数的最大值保证其可见性

最后可以看一下实现效果DEMO

原创粉丝点击