Skip to main content

全屏显示

Flash has offered a full-screen mode for many years but, until now, browser vendors have resisted the feature. The main reason: security. If you can force an app to run full-screen, the user loses their browser, taskbar and standard operating system controls. They may not be able to close the window or, worse, nefarious developers could emulate the OS and trick users into handing over passwords, credit card details, etc.

At the time of writing, the HTML5 full-screen API has been implemented in Firefox, Chrome and Safari. Mozilla provide good cross-browser details but it’s worth noting that the specifications and implementation details are likely to change.

Unlike pressing F11 to make your browser go full-screen, the API sets a single element full-screen. It’s intended for images, videos and games using the canvas element. Once an element goes full-screen, a message appears temporarily to inform the user that they can press ESC at any time to return to windowed mode.

The main properties, methods and styles are:

element.requestFullScreen()

Makes an individual element full-screen, e.g. document.getElementById(“myvideo”).requestFullScreen().

document.cancelFullScreen()

Exits full-screen mode and returns to the document view.

document.fullScreen

Returns true if the browser is in full-screen mode.

:full-screen

A CSS pseudo-class which applies to an element when it’s in full-screen mode.

Vexing Vendor Prefixes

Don’t bother trying to use these API names. You’ll require vendor prefixes for BOTH the CSS and JavaScript properties:

StandardChrome/SafariFirefox
.requestFullScreen().webkitRequestFullScreen().mozRequestFullScreen()
.cancelFullScreen().webkitCancelFullScreen().mozCancelFullScreen()
.fullScreen.webkitIsFullScreen.mozfullScreen
:full-screen:-webkit-full-screen:-moz-full-screen

There’s no support in Internet Explorer or Opera yet, but I would suggest you use the ‘ms’ and ‘o’ prefixes for future proofing.

I’ve developed a function in the demonstration page which handles the prefix shenanigans for you:

view plainprint?

var pfx = ["webkit", "moz", "ms", "o", ""];
function RunPrefixMethod(obj, method) {
var p = 0, m, t;
while (p < pfx.length && !obj[m]) {
m = method;
if (pfx[p] == "") {
m = m.substr(0,1).toLowerCase() + m.substr(1);
}
m = pfx[p] + m;
t = typeof obj[m];
if (t != "undefined") {
pfx = [pfx[p]];
return (t == "function" ? obj[m]() : obj[m]);
}
p++;
}
}

We can then make any element viewable full screen by attaching a handler function which determines whether it’s in full-screen mode already and acts accordingly:

view plainprint?

  1. var e = document.getElementById("fullscreen");
  2. e.onclick = function() {
  3. if (RunPrefixMethod(document, "FullScreen") || RunPrefixMethod(document, "IsFullScreen")) {
  4. ​ RunPrefixMethod(document, "CancelFullScreen");
  5. }
  6. else {
  7. ​ RunPrefixMethod(e, "RequestFullScreen");
  8. }
  9. }

The CSS

Once the browser enters full-screen mode you’ll almost certainly want to modify the styles for the element and it’s children. For example, if your element normally has a width of 500px, you’ll want to change that to 100% so it uses the space available, e.g.

view plainprint?

  1. #myelement
  2. {
  3. width: 500px;
  4. }
  5. #myelement:full-screen
  6. {
  7. width: 100%;
  8. }
  9. #myelement:full-screen img
  10. {
  11. width: 100%;
  12. }

However, you cannot use a list of vendor prefixed selectors:

view plainprint?

  1. /* THIS DOES NOT WORK */
  2. #myelement:-webkit-full-screen,
  3. #myelement:-moz-full-screen,
  4. #myelement:-ms-full-screen,
  5. #myelement:-o-full-screen,
  6. #myelement:full-screen
  7. {
  8. width: 100%;
  9. }

For some bizarre reason, you must repeat the styles in their own blocks or they won’t be applied:

view plainprint?

  1. /* this works */
  2. #myelement:-webkit-full-screen { width: 100% }
  3. #myelement:-moz-full-screen { width: 100% }
  4. #myelement:-ms-full-screen { width: 100% }
  5. #myelement:-o-full-screen { width: 100% }
  6. #myelement:full-screen { width: 100% }

Weird.

View the demonstration page in Firefox, Chrome or Safari…

The technique works well. The only issue I’ve discovered concerns Safari on a two-monitor desktop — it insists on using the first monitor for full-screen mode even if the browser is running on the second screen?

While it’s possibly a little early to use full-screen mode, games developers and video producers should keep an eye on progress.

全屏API简史

  1. 第一个原生的全屏接口是在Safari 5.0(和iOS)中添加的 webkitEnterFullScreen() 函数。不过,它只能用于<video>标签。
  2. 在Safari 5.1中,苹果修改了这个API使它更接近于Mozilla的全屏API草案(比苹果的实现更早)。现在,所有DOM元素都可以调用 webkitRequestFullScreen() 方法。
  3. Firefox和Chome表示它们将会添加原生全屏API支持,而且这个特性已经在Chome 15+以及Firefox Nightly中实现。

在2011年10月15日,W3C发布了一份全屏API草案(由Opera团队的一名成员编写),它跟Mozilla的草案有两个主要的不同点:

  1. Mozilla/Webkit使用大写字母'S'(FullScreen),但W3C则不是(Fullscreen);
  2. Mozilla/Webkit使用cancelFullScreen,W3C使用ex****itFullscreen

理解全屏API

检测全屏支持

首先,你需要使用typeof检测浏览器是否支持全屏API。同时,也要检测一个布尔属性fullScreenEnabled,它会告诉你用户是否启用了全屏特性。

// Mozilla草案的API:实际上,你还需要检测其他厂商的前缀

if (typeof document.cancelFullScreen != 'undefined' && document.fullScreenEnabled === true) {

/* do fullscreen stuff */

}

进入和退出全屏

要进入全屏模式,可以调用该元素的requestFullScreen(或者W3C的 requestFullsc****reen)方法。。要退出全屏,则调用docume****nt对象的cancelFullScreen(或者W3C的exit****Fullscreen)方法。

// mozilla草案

element.requestFullScreen();

document.cancelFullScreen();

// Webkit (works in Safari and Chrome)

element.webkitRequestFullScreen();

document.webkitCancelFullScreen();

// Firefox (works in nightly)

element.mozRequestFullScreen();

document.mozCancelFullScreen();

// W3C

element.requestFullscreen();

document.exitFullscreen();

Mozilla还提供了一个备用的requestFullScreenWithKeys()方法让用户可以通过键盘进入全屏模式。在Flash中,Adobe一直在全屏状态时禁止键盘支持,以防止恶意网站试图窃取密码,但浏览器制造商似乎正考虑使之成为一个可选设置。

全屏事件和当前状态

要检测全屏事件的发生,可以监听元素的fullscreeneventchange事件,而docum****ent的布尔属性fullScreen会指明当前是否全屏状态。

element.addEventListener('fullscreeneventchange', function(e) {

if (document.fullScreen) {

​ /* make it look good for fullscreen */

} else {

​ /* return to the normal state in page */

}

}, true);

Mozilla也提到在将来增加一个fullscreendenied事件。另外,Webkit在全屏布尔属性的名字上加了'Is':

// Mozilla草案

document.fullScreen;

// Firefox (Nightly)

document.mozFullScreen;

// Webkit (Chrome, Safari)

document.webkitIsFullScreen; // 注意多了'Is'

// W3C草案

document.fullscreen;

全屏样式

Mozilla和W3C都提供了新的伪CSS类来装饰元素的全屏模式。

/* 普通状态 */

.my-container { width: 640px; height: 360px; }

/* Mozilla草案 (有中划线) */

.my-container:full-screen { width:100%; height:100%;}

/* W3C草案 (无中划线) */

.my-container:fullscreen { width:100%; height:100%;}

/* 当前可用的供应商前缀 */

.my-container:-webkit-full-screen,

.my-container:-moz-full-screen { width:100%; height:100%; }

嵌入元素的全屏

当你使用Flash的<object>、<embed>从其他站点嵌入内容(比如一个YouTuBe视频)是,你可以指定是否允许它们全屏。这个特性也通过allowFullScreen属性添加到<iframe>标签。

<!-- 允许使用全屏命令的外部内容 -->

<iframe src="http://anothersite.com/video/123" width="640" height="360" allowFullScreen="allowFullScreen"></iframe>

进入和退出全屏

// Webkit (works in Safari5.1 and Chrome 15)

element.webkitRequestFullScreen();

document.webkitCancelFullScreen();

// Firefox 10

element.mozRequestFullScreen();

document.mozCancelFullScreen();

// W3C 提议

element.requestFullscreen();

document.exitFullscreen();

事件监听

// Webkit-base: element.onwebkitfullscreenchange

// Firefox: element.onmozfullscreenchange

// W3C Method:

element.addEventListener(‘fullscreenchange’, function(e) {

if (document.fullScreen) { // document.webkitIsFullScreen

/* make it look good for fullscreen */

} else {

/* return to the normal state in page */

}

}, true);

【css伪类】

:fullscreen – 当前全屏化的元素

:fullscreen-ancestor – 所有全屏化元素的祖先元素

【标签属性】

<iframe width=”640″ height=”360″ src=”" allowfullscreen=”"></iframe>

总结

全屏并非简单地去掉浏览器地址栏和状态栏而已,它和按f11进入全屏有不少区别。一点心得:

1)在safari和chrome下,全屏后的元素全自动全屏居中,且背景色变为黑色。我尝试过通过给body设背景色来改变下背景色的颜色,失败。在firefox下,全屏后的背景色为全屏那个元素的背景色,且元素并不居中。如果给body调全屏,在webkit内核的浏览器下和按11进入的全屏效果差得很远,主要是背景色问题,而firefox下则效果接近于f11全屏——当然还是有区别,比如进入全屏的动画过程就不相同。

2)退出全屏是通过给document来调来cancelFullScreen方法,但如果想让页面所有元素全部进入全屏的话,不能给document调requestFullScreen,只能给body调。

3)onFullScreenChange事件的回调,在safari里不能写alert,如果写alert,点击后会自动退出全屏。

4)按f11进入的全屏,onFullScreenChange事件不会响应。

5)进入全屏一定要点击某个节点,不能直接调进入全屏api。mouseover、mousemove等接近onload的事件也不行。click、mousedown、mouseup事件可以。策略应该同window.open应该是一样的。

6)ios暂不支持全屏api。