使用 Page Visibility API

Ernest Delgado
Ernest Delgado

簡介

身為網頁程式開發人員,我們因為能夠建立更具吸引力和互動性更高的網頁,而引人矚目。想透過 WebGL 處理 3D 圖形?當然可以。是否可透過 WebAudio 提供進階音訊功能?沒問題,即時協作應用程式是否使用網路攝影機和麥克風?立即申請!

雖然不那麼令人興奮,但同樣重要的是,這些技術可讓我們建立運作效率更高、提供更優質整體使用者體驗的應用程式。這時就需要 PageVisibility 這類 API 的協助。

Page Visibility API 的用途是執行簡單但重要的功能,可在使用者看到頁面時通知應用程式。這項基本資訊可讓您建立在未顯示時會以不同方式運作的網頁。請參考以下幾個範例:

  • 從伺服器擷取資訊的網頁,在沒有人積極查看時,可能會減緩更新週期
  • 顯示輪轉圖片輪轉介面或影片/音訊內容的網頁,可在使用者再次顯示該網頁前暫停
  • 應用程式只能在通知隱藏時,決定是否向使用者顯示通知

起初,這個 API 除了方便使用者之外,似乎沒有太大用處,但考量到行動版網頁瀏覽量大幅增加,任何有助於節省裝置電力的做法都非常重要。只要使用 PageVisibility API,網站就能協助使用者在裝置上減少耗電量和續航力。

瀏覽器支援

  • Chrome:33。
  • 邊緣:12。
  • Firefox:18。
  • Safari:7。

資料來源

這個 API 規格目前處於候選推薦階段,提供用於偵測文件可見度狀態的屬性,以及用於回應可見度變更的事件。

在本教學課程中,我會介紹 API 的基本概念,並說明如何將其應用於一些實際範例 (如果您是急性子,可以直接跳到這些範例)。

文件瀏覽權限屬性

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

如您所料,如果文件完全無法顯示,隱藏屬性會傳回 true。通常表示文件已最小化、位於背景分頁上、OS 的鎖定畫面已開啟等。如果文件的任何部分至少在一個螢幕上顯示部分內容,則屬性會設為 false。此外,為配合無障礙工具,當螢幕放大鏡等工具完全遮蔽文件,但仍顯示該文件的檢視畫面時,可以將 hidden 屬性設為 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 扮演了重要的角色。如要進一步瞭解如何建構資源節約型網頁應用程式,請參閱其他效能相關文章

外部參考資料