Web全屏模式

轉自 Web全屏模式輕鬆掌握

CodePen Demo

地址:演示codejavascript

進去看看,玩一下,本文將結合這個demo一塊兒進行講解。 css

全屏功能封裝在一個類裏面:

我把全屏模式封裝在一個類裏面,在代碼中有詳細的註釋,若是有須要的話,直接把類拿出來,根據栗子和註釋使用便可。html

代碼在codepen的demo裏。java

何謂全屏?

MDN介紹web

使用提供的API,讓一個元素與其子元素,能夠佔據整個屏幕,並在此期間,從屏幕上隱藏全部的瀏覽器用戶界面以及其餘應用。chrome

chrome下的全屏表現api

全屏會隱藏標籤欄,書籤欄瀏覽器

若是網頁一開始不是所有撐開的形式,全屏下,也會將要全屏的元素充滿整個屏幕bash

能夠多層全屏,如栗子中同樣,能夠先左邊全屏,而後紅色全屏。dom

在這種狀況下退出全屏,只會退出紅色全屏,退回到左邊全屏的形式,因此頁面依然是全屏模式。

進入全屏時,有一個默認的提示:'按esc便可退出全屏模式',以下圖顯示: ![](data:image/svg+xml;utf8,<?xml version="1.0"?><svg xmlns="www.w3.org/2000/svg" version="1.1" width="1280" height="131"></svg>) 5. 當按Esc或調用退出全屏方法,退出全屏。標籤欄和書籤欄依然是隱藏的,網頁上的元素恢復成本來的尺寸

要顯示書籤欄和標籤欄,須要刷新一下頁面。


全屏API:

總共用到6個API

  1. 瀏覽器是否支持全屏模式:document.fullscreenEnabled
  2. 使元素進入全屏模式:Element.requestFullscreen()
  3. 退出全屏:document.exitFullscreen()
  4. 檢查當前是否有節點處於全屏狀態:document.fullscreenElement
  5. 進入全屏/離開全屏,觸發事件:document.fullscreenchange
  6. 沒法進入全屏時觸發: document.fullscreenerror

瀏覽器前綴:

目前並非全部的瀏覽器都實現了API的無前綴版本,因此咱們須要針對不一樣瀏覽器,作一下API的兼容:

這是我在demo中作的瀏覽器兼容:

/**
 * @description: 是否支持全屏+判斷瀏覽器前綴
 * @param {Function} fn 不支持全屏的回調函數 這裏設了一個默認值
 */
isFullscreen(fn) {
  let fullscreenEnabled;
  // 判斷瀏覽器前綴if (document.fullscreenEnabled) {
    fullscreenEnabled = document.fullscreenEnabled;
  } elseif (document.webkitFullscreenEnabled) {
    fullscreenEnabled = document.webkitFullscreenEnabled;
    this.prefixName = 'webkit';
  } elseif (document.mozFullScreenEnabled) {
    fullscreenEnabled = document.mozFullScreenEnabled;
    this.prefixName = 'moz';
  } elseif (document.msFullscreenEnabled) {
    fullscreenEnabled = document.msFullscreenEnabled;
    this.prefixName = 'ms';
  }
  if (!fullscreenEnabled) {
    if (fn !== undefined) fn(); // 執行不支持全屏的回調this.isFullscreenData = false;
  }
}
複製代碼
複製代碼

我在實例化的時候進行一次判斷瀏覽器是否支持全屏,而後保存瀏覽器前綴

推薦這麼作,由於若是每一個API都要這樣重複的判斷瀏覽器前綴,那也太噁心了!

1. 瀏覽器是否支持全屏模式:document.fullscreenEnabled

document.fullscreenEnabled屬性返回一個布爾值,表示當前文檔是否能夠切換到全屏狀態。

代碼在上方瀏覽器前綴代碼中給出了。

若是沒有保存瀏覽器前綴的話,注意作一下不一樣瀏覽器前綴的兼容!下面再也不強調

2. 使元素進入全屏模式:Element.requestFullscreen()

/**
 * @description: 將傳進來的元素全屏
 * @param {String} domName 要全屏的dom名稱
 */
Fullscreen(domName) {
  const element = document.querySelector(domName); // 獲取domconst methodName =
    this.prefixName === ''
      ? 'requestFullscreen'
      : `${this.prefixName}RequestFullScreen`; // API前綴
  element[methodName](); // 調用全屏
}
複製代碼
複製代碼

這就是咱們實現全屏的API,是否是超簡單?

值得注意的是:調用此API並不能保證元素必定可以進入全屏模式

MDN:例如<iframe> 元素具備 allowfullscreen 屬性,可選擇是否將其內容以全屏模式顯示

這種不被容許全屏的元素屬於極少數狀況,我試過能夠將button全屏。

全屏請求必須在事件處理函數(點擊事件等)中調用,不然將會被拒絕。

demo中有演示,初始化直接全屏,會觸發進入全屏失敗回調。

3. 退出全屏:document.exitFullscreen()

介紹

exitFullscreen() {
  const methodName =
    this.prefixName === ''
      ? 'exitFullscreen'
      : `${this.prefixName}ExitFullscreen`; // API 前綴document[methodName](); // 調用
}
複製代碼
複製代碼

調用這個方法會讓文檔回退到上一個調用Element.requestFullscreen()方法進入全屏模式以前的狀態。

多層全屏

demo中,先進入左邊全屏,再進入紅色全屏,即爲:多層全屏的狀況(雖然這種狀況並很少)。

當出現多層全屏的狀況,須要一層層的退出到頁面最初始的狀況,並非調用一次document.exitFullscreen()就恢復到頁面最初始的樣子。

4. 檢查當前是否有節點處於全屏狀態:document.fullscreenElement

fullscreenElement屬性返回正處於全屏狀態的Element節點,若是當前沒有節點處於全屏狀態,則返回null

/**
 * @description: 檢測有沒有元素處於全屏狀態
 * @return 布爾值
 */
isElementFullScreen() {
  const fullscreenElement =
    document.fullscreenElement ||
    document.msFullscreenElement ||
    document.mozFullScreenElement ||
    document.webkitFullscreenElement; // 有前綴的f是大寫,沒前綴是小寫if (fullscreenElement === null) {
    returnfalse; // 當前沒有元素在全屏狀態
  } else {
    returntrue; // 有元素在全屏狀態
  }
}
複製代碼
複製代碼

事實上,還有一個屬性document.fullscreen,返回一個布爾值,表示文檔是否處於全屏模式。

兩個方法效果是同樣,但由於IE不支持這個屬性,因此這裏用的是document.fullscreenElement

5. 進入全屏/離開全屏,觸發事件:document.fullscreenchange

當咱們進入全屏和離開全屏的時候,都會觸發一個fullscreenchange事件。

MDN注意:此事件不會提供任何信息,代表是進入全屏或退出全屏

看了很久事件返回的信息,確實找不到一個值,代表這是在進入全屏,或者離開全屏!

能夠說至關不人性化了!但咱們能夠經過檢查當前是否有節點處於全屏狀態,判斷當前是否處於全屏模式。

/**
 * @description: 監聽進入/離開全屏
 * @param {Function} enter 進入全屏的回調
 *  @param {Function} quit 離開全屏的回調
 */
screenChange(enter,quit) {
  if (!this.isFullscreenData) return;
  const methodName = `on${this.prefixName}fullscreenchange`;
  document[methodName] = e => {
    if (this.isElementFullScreen()) {
      enter && enter(e); // 進入全屏回調
    } else {
      quit && quit(e); // 離開全屏的回調
    }
  };
}
複製代碼
複製代碼

注意:多層全屏的狀況

  1. 先進入左邊全屏(進入全屏回調),再進入紅色全屏(進入全屏回調)
  2. 退出全屏,此時退出紅色全屏,左邊還是全屏(觸發進入全屏回調)
  3. 出現這種狀況,能夠在點擊按鈕的時候,作一些狀態限制。或者根據全屏事件返回的dom信息來進行判斷。

6. 沒法進入全屏時觸發: document.fullscreenerror

進入全屏並不老是成功的,多是技術緣由,也多是用戶拒絕,咱們在上文進入全文的APIElement.requestFullscreen()部分講過了。

好比全屏請求不是在事件處理函數中調用,會在這裏攔截到錯誤

/**
 * @description: 瀏覽器沒法進入全屏時觸發
 * @param {Function} enterErrorFn 回調
 */
screenError(enterErrorFn) {
  const methodName = `on${this.prefixName}fullscreenerror`;
  document[methodName] = e => {
    enterErrorFn && enterErrorFn(e)
  };
}
複製代碼
複製代碼

Css: 全屏模式下的樣式

chorme 70 下的默認會爲正在全屏的dom添加兩個class:稍微看一下

  1. 默認設置黑色背景

    :not(:root):-webkit-full-screen::backdrop { position: fixed; top: 0px; right: 0px; bottom: 0px; left: 0px; background: black; // 會將背景設爲黑色的 若是你沒爲你的dom設置背景的話,全屏下會爲黑色 } 複製代碼

  2. 默認樣式:

    :not(:root):-webkit-full-screen { object-fit: contain; position: fixed !important; top: 0px!important; right: 0px!important; bottom: 0px!important; left: 0px!important; box-sizing: border-box !important; min-width: 0px!important; max-width: none !important; min-height: 0px!important; max-height: none !important; width: 100%!important; height: 100%!important; transform: none !important; margin: 0px!important; } 複製代碼

全屏狀態的CSS:

全屏狀態下,大多數瀏覽器的CSS支持:full-screen僞類,只有IE11支持:fullscreen僞類。使用這個僞類,能夠對全屏狀態設置單獨的CSS屬性。

如下css摘自阮一峯老師的Fullscreen API:全屏操做

/* 針對dom的全屏設置 */.div:-webkit-full-screen {
  background: #fff;
}
/* 全屏屬性 */:-webkit-full-screen {}
:-moz-full-screen {}
:-ms-fullscreen {}
/* 全屏僞類 當前chrome:70 不支持 */:full-screen {
}
:fullscreen {
  /* IE11支持 */
}
複製代碼
複製代碼

完整DEMO

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			.top {
				margin: 15px;
			}
			
			.main {
				width: 100%;
				height: 1000px;
				display: flex;
			}
			
			.left {
				width: 50%;
				height: 60%;
				background: gray;
				padding: 20px;
			}
			
			.left-son {
				width: 80%;
				height: 50%;
				margin: 15px;
				background: red;
			}
			
			.right {
				width: 50%;
				height: 60%;
				background: #dddddd;
			}
			/* 針對dom的全屏設置 */
			
			.left:-webkit-full-screen {
				background: #fff;
			}
			/* 全屏屬性 */
			
			:-webkit-full-screen {}
			
			:-moz-full-screen {}
			
			:-ms-fullscreen {}
			/* 全屏僞類 當前chrome:70 不支持 */
			
			:full-screen {}
			
			:fullscreen {
				/* IE11支持 */
			}
		</style>
	</head>

	<body>

		<div class="top">
			<button onclick="leftScreen()">左邊全屏</button>
			<button onclick="rightScreen()">右邊全屏</button>
		</div>
		<div class="main">
			<div class="left">
				<button onclick="redScreen()">紅色全屏</button>
				<button onclick="exitScreen()">退出全屏</button>
				<div class="left-son">
					<button onclick="exitScreen()">紅色退出全屏</button>
					<span>左邊的內容</span>
				</div>
			</div>
			<div class="right">右邊的內容</div>
		</div>
	</body>
	<script type="text/javascript">
		class fullScreen {
			/**
			 * @description: 全屏初始化
			 * @param {Function} fn 用戶瀏覽器不支持全屏的回調
			 */
			constructor(fn) {
				this.prefixName = ""; // 瀏覽器前綴
				this.isFullscreenData = true; // 瀏覽器是否支持全屏
				this.isFullscreen(fn);
			}
			/**
			 * @description: 將傳進來的元素全屏
			 * @param {String} domName 要全屏的dom名稱
			 */
			Fullscreen(domName) {
				const element = document.querySelector(domName);
				const methodName =
					this.prefixName === "" ?
					"requestFullscreen" :
					`${this.prefixName}RequestFullScreen`;
				element[methodName]();
			}
			// 退出全屏
			exitFullscreen() {
				const methodName =
					this.prefixName === "" ?
					"exitFullscreen" :
					`${this.prefixName}ExitFullscreen`;
				document[methodName]();
			}
			/**
			 * @description: 監聽進入/離開全屏
			 * @param {Function} enter 進入全屏的回調
			 *  @param {Function} quit 離開全屏的回調
			 */
			screenChange(enter, quit) {
				if(!this.isFullscreenData) return;
				const methodName = `on${this.prefixName}fullscreenchange`;
				document[methodName] = e => {
					if(this.isElementFullScreen()) {
						enter && enter(e); // 進入全屏回調
					} else {
						quit && quit(e); // 離開全屏的回調
					}
				};
			}
			/**
			 * @description: 瀏覽器沒法進入全屏時觸發,多是技術緣由,也多是用戶拒絕:好比全屏請求不是在事件處理函數中調用,會在這裏攔截到錯誤
			 * @param {Function} enterErrorFn 回調
			 */
			screenError(enterErrorFn) {
				const methodName = `on${this.prefixName}fullscreenerror`;
				document[methodName] = e => {
					enterErrorFn && enterErrorFn(e);
				};
			}
			/**
			 * @description: 是否支持全屏+判斷瀏覽器前綴
			 * @param {Function} fn 不支持全屏的回調函數 這裏設了一個默認值
			 */
			isFullscreen(fn) {
				let fullscreenEnabled;
				// 判斷瀏覽器前綴
				if(document.fullscreenEnabled) {
					fullscreenEnabled = document.fullscreenEnabled;
				} else if(document.webkitFullscreenEnabled) {
					fullscreenEnabled = document.webkitFullscreenEnabled;
					this.prefixName = "webkit";
				} else if(document.mozFullScreenEnabled) {
					fullscreenEnabled = document.mozFullScreenEnabled;
					this.prefixName = "moz";
				} else if(document.msFullscreenEnabled) {
					fullscreenEnabled = document.msFullscreenEnabled;
					this.prefixName = "ms";
				}
				if(!fullscreenEnabled) {
					this.isFullscreenData = false;
					fn && fn(); // 執行不支持全屏的回調
				}
			}
			/**
			 * @description: 檢測有沒有元素處於全屏狀態
			 * @return 布爾值
			 */
			isElementFullScreen() {
				const fullscreenElement =
					document.fullscreenElement ||
					document.msFullscreenElement ||
					document.mozFullScreenElement ||
					document.webkitFullscreenElement;
				if(fullscreenElement === null) {
					return false; // 當前沒有元素在全屏狀態
				} else {
					return true; // 有元素在全屏狀態
				}
			}
		}
		let full = new fullScreen(() => {
			console.log("不支持");
		});
		full.screenError(e => {
			console.log("進去全屏失敗:", e);
		});
		// 全屏請求必須在事件處理函數中調用,不然將會被拒絕。
		full.Fullscreen(".left"); // 觸發進去全屏失敗回調
		const obj = {
			enter: e => {
				// 若是退出全屏 退出的仍是全屏狀態,將會觸發進入全屏的回調,這種狀況比較少 注意一下
				console.log("進入全屏", e);
			},
			quit: e => {
				console.log("退出全屏", e);
				// 一般不會出現嵌套的狀況
			}
		};
		full.screenChange(obj.enter, obj.quit);

		function leftScreen() {
			full.Fullscreen(".left");
		}

		function rightScreen() {
			full.Fullscreen(".right");
		}

		function redScreen() {
			full.Fullscreen(".left-son");
		}
		// 退出全屏 退出到上次的狀態
		function exitScreen() {
			full.exitFullscreen();
		}
	</script>

</html>
複製代碼

結語

咱們能夠把全屏技術應用在H5遊戲、信息流網站、視頻等地方,下次再有全屏需求時,記住不要慌,回頭看看過本文的栗子,把我封裝的類拿出來直接用就能夠啦!

相關文章
相關標籤/搜索