移動端瀏覽器中的video元素是比較特別的,早期無論是在iOS還是Android的瀏覽器中,它都位於頁面的最頂層,無法被遮蓋。後來這個問題在iOS下得到了解決,但是Android的瀏覽器則問題依舊。X5是騰訊基於Webkit開發的渲染引擎,它提供了一種名叫「同層播放器」的特殊video元素以解決遮蓋問題。
簡單使用
同層播放器的使用方式跟普通的video元素差別不大,只是需要加上兩個X5的自定義屬性:「x5-video-player-type」和「x5-video-player-fullscreen」。
下面做一個測試頁面嵌入同層播放器:
body {
margin: 0;
background: #000;
font-size: 0.3rem;
}
.player {
width: 100%;
height: 4.22rem;
}
.player .video {
width: 100%;
height: 100%;
}
複製程式碼
<video id="video" class="video" controls="controls" playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true">
<source src="video.mp4" />
</video>
複製程式碼
點選播放後,video元素佔全屏,視訊部分預設居中顯示:
調整位置
按照官方文件所述,只要修改video元素的「object-position」屬性,就可以修改視訊部分的顯示位置,但實際上還要把video元素的寬高設成螢幕的寬高才行:
.fullscreen .video {
object-position: center top;
}
複製程式碼
var player = document.getElementById(`video`);
player.addEventListener(`x5videoenterfullscreen`, function() {
// 設為螢幕尺寸
player.style.width = window.screen.width + `px`;
player.style.height = window.screen.height + `px`;
// 在body上新增樣式類以控制全屏下的展示
document.body.classList.add(`fullscreen`);
});
player.addEventListener(`x5videoexitfullscreen`, function() {
player.style.width = player.style.height = ``;
document.body.classList.remove(`fullscreen`);
}, false);
複製程式碼
效果如下(右圖):
注意把video元素的高設為螢幕高度時,要用「window.screen.height」而不能用「document.documentElement.clientHeight」,因為後者不包含導航欄高度,將會導致無法滿屏(如上方左圖所示)。
全屏狀態下的佈局
下面加上標題欄:
.header {
width: 100%;
height: 1.14rem;
line-height: 1.14rem;
background: #fff;
font-size: 0.36rem;
text-align: center;
color: #000;
}
複製程式碼
<header id="header" class="header">標題欄</header>
<div class="player">
<video id="video" class="video" controls="controls" playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true">
<source src="video.mp4" />
</video>
</div>
複製程式碼
然而,點選播放進入全屏狀態後,標題欄就消失不見了。既然同層播放器是可以被遮蓋的,那就試試絕對定位吧:
.fullscreen .header {
position: absolute;
top: 0;
left: 0;
z-index: 9999;
}
複製程式碼
標題欄確實遮擋住視訊了,但是就多了一層黑色的漸變以及左右兩個按鈕(下方左圖)。據官方文件所述,這些都是無法移除的。
接下來要做的是把視訊下移,使整體UI與進入全屏前保持一致(上方右圖):
.fullscreen .player .video {
object-position: center 1.14rem;
}
複製程式碼
下一步是在video元素後面新增其他內容:
.main {
height: 5rem;
background: #fff;
}
.main .inner {
padding: 0.3rem;
}
複製程式碼
<header id="header" class="header">標題欄</header>
<div class="player">
<video id="video" class="video" controls="controls" playsinline x5-video-player-type="h5" x5-video-player-fullscreen="true">
<source src="video.mp4" />
</video>
</div>
<div id="main" class="main">
<div class="inner">這裡是其他內容</div>
</div>
複製程式碼
然而,進入全屏狀態後,內容元素向上偏移了(下方左圖)。
明顯地,該元素的位置也要下移標題欄的高度:
.fullscreen .main {
margin-top: 1.14rem;
}
複製程式碼
接下來嘗試簡單的點選事件響應:
var main = document.getElementById(`main`);
main.addEventListener(`click`, function() {
this.querySelector(`.inner`).innerHTML = Date.now();
}, false);
複製程式碼
此時進入全屏狀態後點選內容元素是沒有任何反應的,因為video元素佔滿屏,而它的層級偏高,把內容元素擋住了。知道問題之後,解決方案也很簡單,只要把main元素的層級調高就好了:
.fullscreen .main {
position: relative;
}
複製程式碼
橫屏狀態下進入全屏
因為同層播放器的全屏狀態只能指定一個方向(預設為豎屏),所以播放後還是會強制豎屏。此時整體效果都不太對勁:
因為橫屏狀態的寬高與豎屏狀態下的剛好相反,所以才導致恢復豎屏時的UI異常。因此,進入全屏時要判斷一下寬高,如果寬大於高,則將其交換:
player.addEventListener(`x5videoenterfullscreen`, function() {
var width = window.screen.width;
var height = window.screen.height;
if (width > height) {
width = [height, height = width][0];
}
player.style.width = width + `px`;
player.style.height = height + `px`;
document.body.classList.add(`fullscreen`);
}, false);
複製程式碼
其他問題
如果播放前頁面有滾動條,進入全屏狀態下可以滾動嗎?答案是確實可以滾動,但是與其叫滾動,不如叫抖動,具體效果可以自己嘗試。總之進入全屏狀態後就不要用頁面的滾動了,而是用區域性滾動。此外還應注意,因為調高了層級,如果內容元素太高,就會擋住視訊的控制條。
最後一個問題是,播放某些格式的視訊時,進度條會出現錯亂,即使返回非全屏模式時也還是錯亂。
總結
- 關於同層播放器的支援情況,官方文件有詳細描述,最新的微信、QQ以及QQ瀏覽器都能支援,但是僅限Android平臺。
- 雖然同層播放器可以解決遮蓋video元素的問題,但這畢竟還是X5 Only的技術。如果頁面要在非騰訊系的產品中開啟,那就要注意處理相容問題。
- 同層播放器之前的元素,要用絕對定位或固定定位才能展示出來;而其後的元素,只要往下偏移(播放器元素「object-position」指定的偏移)並且提高層級,就與未播放時無異了。
本文也釋出在作者個人部落格:X5同層播放器試用報告 | 前端開發 | Heero`s Blog