JS 監聽瀏覽器各個標籤間的切換
這篇文章是別人寫的,覺得挺實用就搬過來了,跟大家分享一下。
以前看到過一些網頁,在標籤切換到其它地址時,網頁上的標題上會發生變化,一直不知道這個是怎麼做的,最近查了一些資料才發現有一個 visibilitychange 事件就可以搞定,這裡將介紹一下頁面可見性(Page Visibility)API的簡單應用。
visibilitychange事件介紹
簡單的說,當用戶最小化網頁或移動到另一個標籤時,API會發送 visibilitychange 有關該網頁的可見性的事件。你可以檢測到該事件並執行一些操作或行為。例如:標籤頁隱藏的時候停止播放音樂視訊、停止一些不必要的輪詢,還有停止一些諸如輪播等迴圈動畫效果等等。這些可以節省伺服器和本地的開銷。
用例
-
網站有一個圖片輪播,不應前進到下一張幻燈片,除非使用者正在檢視該頁面。
-
顯示資訊儀表板的應用程式不希望在頁面不可見時輪詢伺服器以進行更新。
-
網頁要檢測其是否正在進行預渲染,以便其可以準確計算網頁瀏覽量。
以前開發人員往往在客串上註冊 onblur 和onfocus 來檢測頁面是不是活動頁面,但它不會告訴您頁面對使用者是隱藏的。Page Visibility API 解決了這個問題。
瀏覽器相容性
這個事件已經得到現代瀏覽器廣泛的支援,不過一些老版本的瀏覽器需要加相應的字首。
Chrome (Webkit) | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
13字首webkit 33無需字首 |
10字首moz 18無需字首 |
10字首ms | 12.10 | 7 |
document的可見性屬性
Page Visibility (Second Edition) 中定義了2個只讀的 document 屬性:hidden 和 visibilityState。
其中 document.hidden
visible : 頁面內容至少部分可見。這意味著在實際情況中,該網頁是一個非最小化視窗的可見標籤頁。
hidden : 頁面內容是對使用者不可見。實際上,這意味著該文件是後臺標籤頁或最小化視窗的一部分,或者系統鎖屏是時的狀態。
prerender : 網頁內容被預渲染並且使用者不可見。
unloaded : 如果文件被解除安裝,那麼這個值將被返回。
一般情況下我們使用 document.hidden 就能滿足通常的需求。
為了支援老版本的瀏覽器,我們需要對 document.hidden 在做一些字首處理:
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; }
同樣的,我們可以獲取 document.visibilityState 屬性:
function getVisibilityState() { var prefixes = ['webkit', 'moz', 'ms', 'o']; if ('visibilityState' in document) return 'visibilityState'; for (var i = 0; i < prefixes.length; i++) { if ((prefixes[i] + 'VisibilityState') in document) return prefixes[i] + 'VisibilityState'; } // otherwise it's not supported return null; }
這樣我們可以寫一個跨瀏覽器的函式,檢查文件是否可見。
function isHidden() { var prop = getHiddenProp(); if (!prop) return false; return document[prop]; }
visibilitychange監聽事件
你可以在 document物件上註冊一個監聽 visibilitychange 事件,根據 document.hidden 或者 document.visibilityState 屬性做一些業務邏輯:
// 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, function () { document.title = document[getVisibilityState()]+"狀態"; }, false); }