瀏覽器頁面可見性事件詳解及基本應用

頁面可見性改變事件 visibilitychangehtml

詳解


Page Visibility API 標準概述

這是一個頁面可見性API,瀏覽器標籤頁被隱藏或顯示的時候會觸發 visibilitychange事件。web

這是 HTML5 新提供的一個 api ,做用是記錄當前標籤頁在瀏覽器中的激活狀態。
所謂「激活狀態」指當前標籤是否正在被用戶瀏覽。api

咱們知道,平時在 PC 端瀏覽網頁的時候,使用的都是選項卡這種方式瀏覽網頁,使用這種方式瀏覽,任何給定網頁都有可能在後臺,所以對用戶不可見。頁面可見性 API 提供了開發者能夠觀察的事件,以便了解文檔什麼時候可見或隱藏,以及查看頁面當前可見性狀態的功能。瀏覽器

頁面可見性 API 對於節省資源和提到性能特別有用,它使頁面在文檔不可見時避免執行沒必要要的任務。服務器

當用戶最小化窗口或切換到另外一個選項卡時,API會發送 visibilitychange 事件,讓開發者知道頁面狀態已更改。你能夠檢測事件並執行某些操做或行爲。例如,若是你的網絡應用正在播放視頻,則能夠在用戶將標籤放入背景時暫停視頻,並在用戶返回標籤時恢復播放。 用戶不會在視頻中丟失位置,視頻的音軌不會干擾新前景選項卡中的音頻,而且用戶在此期間不會錯過任何視頻。這種體驗是用戶無感知的,而且對於用戶體驗是很是友好的。網絡

規範的使用這個API能夠減小對用戶寬帶的佔用,減小服務器壓力,節省用戶內存,以及到達更好的播放效果。ide


使用場景

  • 網站有圖片輪播效果,只有在用戶觀看輪播的時候,纔會自動展現下一張幻燈片。
  • 顯示信息儀表盤的應用程序不但願在頁面不可見時輪詢服務器進行更新。
  • 頁面想要檢測是否正在渲染,以即可以準確的計算網頁瀏覽量(埋點使用場景)。
  • 當設備進入待機模式時,網站想要關閉設備聲音(用戶按下電源鍵關閉屏幕)。

該API的屬性和事件

HTML5 中專門爲 document 元素添加了相關屬性和事件:post


屬性

    1. Document.hidden 只讀屬性 布爾值 簡單的表示標籤頁顯示或者隱藏
      若是頁面處於被認爲是對用戶隱藏狀態時返回 true ,不然返回 false
    1. Document.visibilityState 只讀屬性
      是一個用來展現文檔可見性狀態的字符串,可能的值:
    • visible : 頁面內容至少是部分可見。 在實際中,這意味着頁面是非最小化窗口的前景選項卡。
    • hidden : 頁面內容對用戶不可見。 在實際中,這意味着文檔能夠是一個後臺標籤,或是最小化窗口的一部分,或是在操做系統鎖屏激活的狀態下。
    • prerender : 頁面內容正在被預渲染且對用戶是不可見的(被 document.hidden 當作隱藏). 文檔可能初始狀態爲 prerender,但毫不會從其它值轉爲該值。 註釋:瀏覽器支持是可選的。
    • unloaded : 頁面正在從內存中卸載。 註釋:瀏覽器支持是可選的。
    1. Document.onvisibilitychange
    • EventListener 提供在visibilitychange 事件被觸發時要調用的代碼。

基本應用


監聽該頁面可視狀態

function onVisibilityChange() {
  if (!document[this.hiddenProperty]) {
    console.log('頁面顯示');
  } else {
    console.log('頁面隱藏');
  }
}

function addVisibilityListener() {
  var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null;
  var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
  document.addEventListener(visibilityChangeEvent, onVisibilityChange, false);
}

function removeVisilityListener() {
  var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'mozHidden' : null;
  var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange');
  document.removeEventListener(visibilityChangeEvent, onVisibilityChange, false);
}

控制視頻暫停⏸播放▶示例

// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
  hidden = "hidden";
  visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
  hidden = "msHidden";
  visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
  hidden = "webkitHidden";
  visibilityChange = "webkitvisibilitychange";
}

var videoElement = document.getElementById("videoElement");

// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
  if (document[hidden]) {
    videoElement.pause();
  } else {
    videoElement.play();
  }
}

// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || hidden === undefined) {
  console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
  // Handle page visibility change
  document.addEventListener(visibilityChange, handleVisibilityChange, false);

  // When the video pauses, set the title.
  // This shows the paused
  videoElement.addEventListener("pause", function(){
    document.title = 'Paused';
  }, false);

  // When the video plays, set the title.
  videoElement.addEventListener("play", function(){
    document.title = 'Playing';
  }, false);
}

應用實例場景:帶有聲音的視頻

在此例中,當你切換到另外一個標籤時視頻會暫停,當你返回到當前標籤時視頻會再次播放,代碼以下:性能

<main>
  <video id="videoElement" controls="" poster="thumbnail.jpg">
    <source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-Mobile.mp4" type="video/mp4" media="all and (max-width:680px)">
    <source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-Mobile.webm" type="video/webm" media="all and (max-width:680px)">
    <source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-SD.mp4" type="video/mp4">
    <source src="https://s3-ap-northeast-1.amazonaws.com/daniemon/demos/The%2BVillage-SD.webm" type="video/webm">
    <p>Sorry, there's a problem playing this video. Please try using a different browser.</p>
  </video>
</main>
// 設置隱藏屬性和改變可見屬性的事件的名稱
  var hidden, visibilityChange;
  if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
    hidden = "hidden";
    visibilityChange = "visibilitychange";
  } else if (typeof document.msHidden !== "undefined") {
    hidden = "msHidden";
    visibilityChange = "msvisibilitychange";
  } else if (typeof document.webkitHidden !== "undefined") {
    hidden = "webkitHidden";
    visibilityChange = "webkitvisibilitychange";
  }

  var videoElement = document.getElementById("videoElement");

  // 若是頁面是隱藏狀態,則暫停視頻;若是頁面是展現狀態,則播放視頻
  function handleVisibilityChange() {
    if (document[hidden]) {
      videoElement.pause();
    } else {
      videoElement.play();
    }
  }

  // 若是瀏覽器不支持addEventListener 或 Page Visibility API 給出警告
  if (typeof document.addEventListener === "undefined" || typeof document[hidden] === "undefined") {
    console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
  } else {

  // 處理頁面可見屬性的改變
  document.addEventListener(visibilityChange, handleVisibilityChange, false);

  // 當視頻暫停,設置title
  // This shows the paused
  videoElement.addEventListener("pause", function(){
    document.title = 'Paused';
  }, false);

  // 當視頻播放,設置title
  videoElement.addEventListener("play", function(){
    document.title = 'Playing'; 
  }, false);
}

兼容性處理

爲了支持老版本的瀏覽器,咱們須要對document.hidden在作一些前綴處理:網站

function getHiddenProp(){
  var prefixes = ['webkit','moz','ms','o'];
  // 若是hidden 屬性是原生支持的,咱們就直接返回
  if ('hidden' in document) {
    return 'hidden';
  }
  // 其餘的狀況就循環現有的瀏覽器前綴,拼接咱們所須要的屬性 
  for (var i = 0; i < prefixes.length; i++){
    // 若是當前的拼接的前綴在 document對象中存在 返回便可
    if ((prefixes[i] + 'Hidden') in document) {
      return prefixes[i] + 'Hidden';
    }  
  }
  // 其餘的狀況 直接返回null
  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';
    }  
  }
  // 找不到返回 null
  return null;
}

visibilitychange監聽事件

你能夠在 document 對象上註冊一個監聽 visibilitychange 事件,根據 document.hidden 或者 document.visibilityState 屬性作一些業務邏輯:

var visProp = getHiddenProp();
if (visProp) {
  // 有些瀏覽器也須要對這個事件加前綴以便識別。
  var evtname = visProp.replace(/[H|h]idden/, '') + 'visibilitychange';
  document.addEventListener(evtname, function () {
    document.title = document[getVisibilityState()]+"狀態";
  },false);
}

上面的代碼會在頁面可見性發生變化時修改 document.title 的值

文章地址:https://www.cnblogs.com/dragonir/p/14417106.html 做者:dragonir

相關文章
相關標籤/搜索