我們可能都有這樣的經曆:打開一個浏覽器,加載之前打開的所有标簽頁,聽到幾個頁面發出的混合在一起的聲音。雖然浏覽器通過标簽的聲音圖示、插件等方法告知使用者發聲的頁面,但這種體驗還是很糟糕。作為開發者和設計者,我們有責任讓網站更受歡迎。
網站是不是應該在被激活使用時才能發出聲音?為什麼我們要浪費資源和程序在我們看不到的動畫上?
幸運的是,現在有一個解決方案:HTML5 有個Page Visibility(頁面可見性)的API。你可以看到
Active Theory 已經在新項目裡使用了這個API。例如 Under Armor 和 A Spacecraft For All 幸運的是,現在有一個解決方案:HTML5 有個頁面可見(Page Visibility)的API。你可以看到:點選其他标簽頁,剛才還在運作的多媒體就會暫停。我喜歡把這樣的網站成為“有禮貌的網站(polite web)”:網站考慮了使用者的注意力、帶寬等。
開發者曾經用綁定
onblur()
onfocus()
事件來嘗試完成這樣的效果。他們這樣比什麼都不做的好,但是這樣的做法不能分辨視窗是否是真的隐藏。比如:有兩個左右并排的視窗,使用者都能看到他們的内容,但是在兩個視窗之間切換時還是或激發 onblur()
或 onfocus()
事件。 使用Page Visibility
有很多使用Page Visibility API的情況,最常見的情況是——頁面有一個視訊,但使用者看不到它,那就沒有必要繼續播放它。
<video autoplay controls id="videoElement">
<source src="rar.mp4">
<source src="rar.webm">
</video>
<script>
var videoElement = document.getElementById("videoElement");
document.addEventListener("visibilitychange", function() {
if (document.hidden) {
videoElement.pause();
} else {
videoElement.play();
}
});
</script>
但是這樣有個問題,讓使用者覺得有點突然:使用者切換标簽時突然打開或停止視訊的聲音。可以把效果改為切換标簽時漸漸顯示或隐藏聲音。這個可以借助jQuery的動畫方法完成。
$("#videoElement").animate({volume: 0}, 1000, "linear", function() {
videoElement.pause();
});
videoElement.play();
$("#videoElement").animate({volume: 1}, 1000, "linear");
規範
Page Visibility API的規範很簡單,隻有兩個方法:
document.hidden
根據浏覽器視窗的狀态傳回
true
false
。具體的狀态存儲在
document.visibilityState
(
hidden
、
visible
prerender
unloaded
)裡。
visibilitychange
可以作為一個事件。
document.visibilityState
可以檢測為什麼document不可見。但是
document.hidden
已經能滿足大部分的需求。
注意事項和浏覽器支援
Page Visibility API采用保守的方式來報告document的隐藏:如果使用者在同一浏覽器視窗裡切換就會報告,但如果是用别的視窗遮住目前頁面,就不會報告。這個API不是萬無一失的,在某些情況下會誤報,使用的時候要小心。
浏覽器對Page Visibility API的支援是比較好的:所有的現代浏覽器(除了Opera Mini)都支援這個API,包括IE10+。供應商字首也慢慢取消:目前需要
-webkit
字首是Android和黑莓的浏覽器。我在上面的代碼中為了簡化操作,沒有加字首。但是添加字首和測試也很友善。
Page Visibility API是Progressive Enhancement(漸進增強)的一個好例子。如果浏覽器不支援這個API,該腳本将被忽略,使用者将像平時一樣被不受控制的聲音打擾。
其他用法
Page Visibility API不僅可以用于聲音和視訊,還可以用于slider 、 PPT。
使用這個API可以使網站更友好、更綠色、更有責任感。建議廣大開發者和設計師考慮把它整合到自己的項目中。