使用 Page Visibility API

歐內斯特德爾加多
Ernest Delgado

引言

身為網頁程式開發人員,我們樂見各種新技術來打造互動性更高、互動性更強的網頁。要透過 WebGL 使用 3D 圖形嗎?當然可以。要支援 WebAudio 的進階音訊功能嗎?沒關係。即時協作應用程式需使用網路攝影機和麥克風嗎?立即申請!

這些技術雖然較不令人興奮,但也很重要,這些技術讓我們可以建構應用程式的執行效率更高,且能提供更優異的整體使用者體驗。這便是 PageVisibility 這類 API 的所在。

Page Visibility API 執行簡單但重要的功能,可讓應用程式知道使用者何時可瀏覽網頁。這項基本資訊可讓您建立網頁,而這些網頁在使用者未觀看的情況下會有不同反應。以下列舉幾個例子:

  • 網頁從伺服器擷取資訊後,如果使用者不積極瀏覽資訊,更新週期速度可能會變慢
  • 顯示旋轉圖片輪轉介面或影片/音訊內容的網頁可能會暫停,直到使用者再次顯示網頁為止
  • 應用程式決定只在對使用者隱藏通知時,才向使用者顯示通知

一開始,這個 API 似乎除了使用者方便之外,有時可能並不實用,但考慮到行動網頁瀏覽數量的大幅增加後,任何有助於節省裝置的電池電力都至關重要。藉由使用 PageVisibility API,您的網站有助於使用者的裝置消耗較少電力,並延長續航力。

瀏覽器支援

  • 33
  • 12
  • 18
  • 7

資料來源

本文中所說的 API 規格 (在本文處於「候選建議」階段) 中提供了偵測文件瀏覽權限狀態的屬性,以及用於回應瀏覽權限變更的事件。

本教學課程將說明 API 的基本概念,並示範如何應用在一些實際的範例 (如果您還不太熟悉,也可以直接跳到範例部分)。

文件瀏覽權限屬性

目前版本的 PageVisibilityAPI 規格會定義兩種文件屬性:布林值 hidden 和列舉 visibilityState。visibilityState 屬性目前有四個可能的值:hiddenvisibleprerenderunloaded

隱藏的屬性會在完全無法查看文件時傳回 true。這通常表示文件已最小化、在背景分頁上、OS 的螢幕鎖定等。如果文件的任一部分至少在一個螢幕畫面中至少有部分顯示,屬性會設為 false。此外,為了配合無障礙工具,如果放大鏡等工具完全遮蔽文件,但現在卻顯示該文件的檢視畫面,隱藏屬性可設為 false。

處理供應商前置字元

為了將焦點放在程式碼上,而非所有供應商專用的前置字串,我要使用部分輔助函式區隔瀏覽器專用項目。一旦停止支援 Android 4.4 瀏覽器,您就可以移除此部分並繼續使用標準名稱。

function getHiddenProp(){
    var prefixes = ['webkit','moz','ms','o'];

    // if 'hidden' is natively supported just return it
    if ('hidden' in document) return 'hidden';

    // otherwise loop over all the known prefixes until we find one
    for (var i = 0; i < prefixes.length; i++){
        if ((prefixes[i] + 'Hidden') in document)
            return prefixes[i] + 'Hidden';
    }

    // otherwise it's not supported
    return null;
}

文件屬性範例

我們現在可以編寫跨瀏覽器函式 isHidden(),檢查文件是否可供檢視。

function isHidden() {
    var prop = getHiddenProp();
    if (!prop) return false;

    return document[prop];
}

如需更精細的文件瀏覽權限,可以使用 visibilityState 屬性。此屬性會傳回下列四個值的其中之一:

  • hidden:文件已完全隱藏,無法查看
  • visible:文件至少有部分在一部顯示裝置上看得到
  • prerender:文件是從畫面外載入且無法顯示 (選用值;並非所有瀏覽器都支援這個值)
  • unloaded:如要卸載文件,系統會傳回這個值 (選用值;並非所有瀏覽器都支援此值)

VisibilityChange 事件

除了瀏覽權限屬性以外,每當文件的瀏覽權限狀態變更時,會觸發顯示設定變更事件。您可以直接在文件物件上註冊這個事件的事件監聽器:

事件範例

// use the property name to generate the prefixed event name
var visProp = getHiddenProp();
if (visProp) {
  var evtname = visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
  document.addEventListener(evtname, visChange);
}

function visChange() {
   var txtFld = document.getElementById('visChangeText');

   if (txtFld) {
      if (isHidden())
         txtFld.value += "Tab Hidden!\n";
      else
         txtFld.value += "Tab Visible!\n";
   }
}

摘要

要建構優質的網頁應用程式,不單只是運用巧思、引人注目,讓使用者可看見並進行互動的功能。真正出色的應用程式會考量使用者的資源和注意力,Page Visibility API 是非常重要的一環。如要進一步瞭解如何建構重視資源的網頁應用程式,請參閱我們的其他效能相關文章

外部參照