原文连接:Hiding and Showing Video Player Controlsjavascript
上周我决定解决一些围绕控制栏的悬而未决的问题,而后进入相关播放器更新的流程。我如今很幸运地有了一些时间,而且我会写一些关于它的更新。css
播放器控制栏的预期行为之一是,当用户在观看视频时处于非活动状态时,它会在几秒钟后淡出。之前,咱们经过video.js实现这一点的方式是经过一些CSS技巧。 当用户的鼠标移出视频播放器区域时,控制栏将被赋予名称为vjs-fade-out
的class。这个class延迟了2秒后有一个转换动效。java
.vjs-fade-out {
display: block;
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 1.5s, opacity 1.5s;
-moz-transition: visibility 1.5s, opacity 1.5s;
-ms-transition: visibility 1.5s, opacity 1.5s;
-o-transition: visibility 1.5s, opacity 1.5s;
transition: visibility 1.5s, opacity 1.5s;
/* 等一下子,而后淡出控制栏 */
-webkit-transition-delay: 2s;
-moz-transition-delay: 2s;
-ms-transition-delay: 2s;
-o-transition-delay: 2s;
transition-delay: 2s;
}
复制代码
当用户的鼠标移回播放器时,该class将被删除,取消全部延迟淡出动效。这提供了一个简单的例子来达成你指望的控件淡出工做效果,只须要几行javascript来添加/删除class。web
player.on('mouseout', function(){
controlBar.addClass('vjs-fade-out');
});
player.on('mouseover', function(){
controlBar.removeClass('vjs-fade-out');
});
复制代码
虽然有一些缺点,但有仍必要摆脱这种方法。浏览器
除了这些问题以外,咱们但愿它可让任何播放器组件或插件hook到隐藏控件的同一个触发器中。像社交分享图标这样的组件应该随控制栏一块儿淡出。框架
首先要添加的东西之一是播放器的userActive
属性,能够是true
或false
。这样作是将控件抽象为咱们实际关心的内容,即用户目前是与播放器互动仍是被动地观看视频。这也使控制栏再也不跟踪用户活动自己,而且容许其余组件经过播放器级别的状态更容易地与控制栏保持一致。ide
该属性的调用是player.userActive()
,并会返回true
或false
。当这个值被改变时,它会触发播放器上的事件。this
player.userActive(true)
// -> 'useractive'事件被触发
player.userActive(false)
// -> 'userinactive'事件被触发
复制代码
播放器元素还添加了vjs-user-active
或vjs-user-inactive
的CSS类名。类名实际上才是用来隐藏和显示控制栏的内容的。spa
.vjs-default-skin.vjs-user-inactive .vjs-control-bar {
display: block;
visibility: hidden;
opacity: 0;
-webkit-transition: visibility 1.5s, opacity 1.5s;
-moz-transition: visibility 1.5s, opacity 1.5s;
-ms-transition: visibility 1.5s, opacity 1.5s;
-o-transition: visibility 1.5s, opacity 1.5s;
transition: visibility 1.5s, opacity 1.5s;
}
复制代码
2秒延迟已从CSS中删除,而是将内置到经过JavaScript timeout将userActive
状态设置为false
的过程当中。只要播放器发生鼠标事件,该timeout就会重置。 例如:插件
var resetDelay, inactivityTimeout;
resetDelay = function(){
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(function(){
player.userActive(false);
}, 2000);
};
player.on('mousemove', function(){
resetDelay();
})
复制代码
mousemove
事件在鼠标移动时会很是迅速地被调用,而且咱们但愿在此操做期间尽量少地阻塞播放器进程,因此咱们使用 John Resig 编写的一种技术。
而不是重置每一个mousemove
的timeout,而是经过mousemove
事件来设置一个变量,该变量能够经过受控的JavaScript时间间隔来获取。
var userActivity, activityCheck;
player.on('mousemove', function(){
userActivity = true;
});
activityCheck = setInterval(function() {
// 检查鼠标是否被移动
if (userActivity) {
// 重置活动跟踪器
userActivity = false;
// 若是用户状态处于非活动状态,请将状态设置为活动状态
if (player.userActive() === false) {
player.userActive(true);
}
// 清除任何现有的不活动超时以启动计时器
clearTimeout(inactivityTimeout);
// 在X秒内,若是没有更多的活动发生,用户将被视为不活动
inactivityTimeout = setTimeout(function() {
// 防止在activityCheck循环拾取下一个用户活动以前能够触发非活动超时的状况。
if (!userActivity) {
this.userActive(false);
}
}, 2000);
}
}, 250);
复制代码
这可能有不少须要遵循的内容,而且与如今播放器中的实际内容相比略微简单一些,但本质上它容许咱们在鼠标移动时从浏览器中获取一些处理权重。
因为新的userActive
状态和延迟的javascript timeout,控件再也不须要鼠标移动到播放器区域外面才会隐藏,如今能够以全屏模式隐藏,就像播放器进入游戏时同样。这也意味着咱们如今能够像使用控件同样隐藏鼠标光标,以便在全屏观看时不会让鼠标出如今播放器上。
.vjs-fullscreen.vjs-user-inactive {
cursor: none;
}
复制代码
触摸设备上的预期行为与桌面浏览器有所不一样。没有mousemove
事件可帮助肯定用户是处于活动状态仍是非活动状态,所以一般会在控件淡出以前添加较长的延迟时间。 此外,虽然在桌面浏览器中点击视频自己一般会在播放和暂停之间切换,但点击移动设备上的视频只会切换控件的可见性。
幸运的是,咱们围绕userActive
创建的框架使得这个最后的部分很容易设置。
video.on('tap', function(){
if (player.userActive() === true) {
player.userActive(false);
} else {
player.userActive(true);
}
});
复制代码
在true
和false
之间手动切换userActive
将应用适当的类名,并触发显示和隐藏控件所需的事件,就像在移动设备上所指望的那样。
tap
事件其实是一个自定义事件,相似于你在jQuery mobile,Hammer.js和其余移动触摸库中发现的tap
事件。每当touchstart
事件触发而且相关的touchend
事件在250毫秒内触发时,就会触发tap
事件。若是touchend
事件须要更长时间才能触发,或者二者之间发生touchmove
事件,则不会将其视为轻敲。
我但愿这篇文章可以深刻了解这些控件在Video.js中的工做方式,以及如何为Video.js构建本身的插件,从而模仿相同的交互。
干杯,
-heff