原文連接: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