跳到主要内容

全屏显示

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: Standard Chrome/Safari Firefox .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?

var e = document.getElementById("fullscreen");
e.onclick = function () {
if (
RunPrefixMethod(document, "FullScreen") ||
RunPrefixMethod(document, "IsFullScreen")
) {
RunPrefixMethod(document, "CancelFullScreen");
} else {
RunPrefixMethod(e, "RequestFullScreen");
}
};

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?

#myelement {
width: 500px;
}
#myelement:full-screen {
width: 100%;
}
#myelement:full-screen img {
width: 100%;
}

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

/* THIS DOES NOT WORK */
#myelement:-webkit-full-screen,
#myelement:-moz-full-screen,
#myelement:-ms-full-screen,
#myelement:-o-full-screen,
#myelement:full-screen {
width: 100%;
}

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

/* this works */
#myelement:-webkit-full-screen {
width: 100%;
}
#myelement:-moz-full-screen {
width: 100%;
}
#myelement:-ms-full-screen {
width: 100%;
}
#myelement:-o-full-screen {
width: 100%;
}
#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 的草案有两个主要的不同点:
  4. Mozilla/Webkit 使用大写字母'S'(FullScreen),但 W3C 则不是(Fullscreen);
  5. Mozilla/Webkit 使用 cancelFullScreen,W3C 使用 exitFullscreen。

理解全屏 API

检测全屏支持

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

// Mozilla 草案的 API:实际上,你还需要检测其他厂商的前缀
if (typeof document.cancelFullScreen != 'undefined' && document.fullScreenEnabled === true) {
/_ do fullscreen stuff _/
}

进入和退出全屏 要进入全屏模式,可以调用该元素的 requestFullScreen(或者 W3C 的 requestFullscreen)方法。。要退出全屏,则调用 document 对象的 cancelFullScreen(或者 W3C 的 exitFullscreen)方法。

// 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 事件,而 document 的布尔属性 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。