Javascript原生全屏API

HTML5中的<video>是一个相当不错的标签,然而在它刚发布的时候一个最大的问题就是它不能像Flash那样实现真正意义上的全屏,幸好接下来的几个月各大浏览器开始原生支持全屏。

我花了一些时间在 MediaElement.js HTML5 video player 中通过不同的方式来实现浏览器全屏,它在 Safari 5.1+, Chrome Canary Chrome 15+, Firefox Nightly(到about:config中设置full-screen-api.enabled= true),并且计划在Firefox10中原生实现这个接口。下面,我将试着解释一下这个API的支持情况,你也可以自己试着修改下面的代码进行测试。

Simple Demo

Video Demo

浏览器全屏API简史

1、第一个实现浏览器原生全屏API的是在Safari 5.0(和iOS)中添加的webkitEnterFullScreen()函数,不过它只能在Safar的<video>标签的controls中(参见: Apple’s HTML5VideoElement)。

2、在Safari 5.1中,苹果更新了这个API使它更接近于Mozilla的全屏API草案(实际上这要比苹果实现的更早),现在,所有的DOM元素都可以调用webkitRequestFullScreen()函数使HTML页面进入到全屏模式。

3、Firefox和Chome宣布它们将会添加原生的全屏API支持,而且这个特性已经在Chome 15+以及Firefox Nightly(Firefox10+)中实现,Mozilla团队已经发布了一些演示

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

  1. Mozilla/Webkit使用大写字母’S’(FullScreen),但W3C则不是(Fullscreen)
  2. Mozilla/Webkit使用cancelFullScreen,W3C使用exitFullscreen

5、更新 (11/15/2011):来自 IEBlog的Ted Johnson说IE10将不会支持全屏API (12/05/2011: 我对Ted的第一封email理解错了)IE10的开发团队还没有决定是否要实现全屏API。不过,他指出:Win8的 Metro风格的Internet Explorer始终是全屏状态,正如以前那样,按F11键即可进入全屏模式。

理解浏览器全屏API

这里是全屏API在不同浏览器中所记录的最重要的部分,一般情况下,下面的例子我都是使用Mozilla/Webkit进行代码的编写,但在必要的地方我也注意到了w3c的差异。

1、检测全屏支持

为了检测浏览全屏支持,你你需要使用typeof检测浏览器是否支持全屏API的方法,同时这也有一个fullScreenEnabled的属性,它将会告诉你是否禁用了该功能(奇怪的是如果禁用的该功能WebKit 就没有fullScreenEnabled这个属性,这将使检测变的困难)

// Mozilla's proposed API: in practice, you'll need vendor prefixes (see examples below)
if (typeof document.cancelFullScreen != 'undefined' && document.fullScreenEnabled === true) {
    /* do fullscreen stuff */
}

2、进入和退出全屏

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

// mozilla proposal
element.requestFullScreen();
document.cancelFullScreen(); 

// Webkit (works in Safari and Chrome Canary)
element.webkitRequestFullScreen(); 
document.webkitCancelFullScreen(); 

// Firefox (works in nightly)
element.mozRequestFullScreen();
document.mozCancelFullScreen(); 

// W3C Proposal
element.requestFullscreen();
document.exitFullscreen();

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

3、浏览器全屏事件和当前状态

要检测全屏事件的发生,可以监听元素的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’,但是w3c草案没有包括这个属性。

4、浏览器全屏样式

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

/* normal state */
.my-container {
    width: 640px;
    height: 360px;
}

/* Mozilla proposal (dash) */
.my-container:full-screen {
    width:100%;
    height:100%;
}

/* W3C proposal (no dash) */
.my-container:fullscreen {
    width:100%;
    height:100%;
}

/* currently working vendor prefixes */
.my-container:-webkit-full-screen, .my-container:-moz-full-screen {
    width:100%;
    height:100%;
}

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

<!-- content from another site that is allowed to use the fullscreen command -->
<iframe src="http://anothersite.com/video/123" width="640" height="360" allowFullScreen></iframe>

最终代码如下:

为了使其在当前状态下工作,你需要封装代码以检测浏览器对全屏API的支持情况,下面我将可以在Safari 5.1, Chrome Canary Chrome 15+, and Firefox Nightly运行的代码合并在了一起,我将会不断更新。

(function() {
    var fullScreenApi = {
            supportsFullScreen: false,
            isFullScreen: function() { return false; },
            requestFullScreen: function() {},
            cancelFullScreen: function() {},
            fullScreenEventName: '',
            prefix: ''
        },
        browserPrefixes = 'webkit moz o ms khtml'.split(' ');

    // check for native support
    if (typeof document.cancelFullScreen != 'undefined') {
        fullScreenApi.supportsFullScreen = true;
    } else {
        // check for fullscreen support by vendor prefix
        for (var i = 0, il = browserPrefixes.length; i < il; i++ ) {
            fullScreenApi.prefix = browserPrefixes[i];

            if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined' ) {
                fullScreenApi.supportsFullScreen = true;

                break;
            }
        }
    }

    // update methods to do something useful
    if (fullScreenApi.supportsFullScreen) {
        fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';

        fullScreenApi.isFullScreen = function() {
            switch (this.prefix) {
                case '':
                    return document.fullScreen;
                case 'webkit':
                    return document.webkitIsFullScreen;
                default:
                    return document[this.prefix + 'FullScreen'];
            }
        }
        fullScreenApi.requestFullScreen = function(el) {
            return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
        }
        fullScreenApi.cancelFullScreen = function(el) {
            return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
        }
    }

    // jQuery plugin
    if (typeof jQuery != 'undefined') {
        jQuery.fn.requestFullScreen = function() {

            return this.each(function() {
                if (fullScreenApi.supportsFullScreen) {
                    fullScreenApi.requestFullScreen(this);
                }
            });
        };
    }

    // export api
    window.fullScreenApi = fullScreenApi;
})();

上面的代码创建了一个名叫fullScreenApi的对象,拥有一个supportsFullScreen属性和其他一些通用的方法,下面是一段示例代码:

if (fullScreenApi.supportsFullScreen) {
    myButton.addEventListener('click', function() {
        fullScreenApi.requestFullScreen(someElement);
    }, true);
}

翻译自:http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/

这篇文章目前没有评论

Leave a Reply

(必填项)

(必填项)

(可选)