按 Esc 键退出全屏时发生了什么?我怎样才能用一个按钮复制它?

What is happening when you press escape to exit fullscreen? How can I replicate it with a button?

我正在尝试为我的 JavaScript canvas 游戏添加全屏选项,它在某些浏览器上可以正常运行,但是 Firefox 的问题让我意识到我的逻辑非常坏了,幸运的是它适用于任何浏览器。

我想在 canvas 上有一个按钮,让您可以切换全屏,但我 运行 遇到了一些问题。我发现的第一个问题是,如果我 canvas.getBoundingClientRect() 调整大小(当我 exit/enter 全屏时),那么在某些浏览器中 cough Firefox,该函数运行得太早并且它在 改变之前得到边界,所以游戏仍然认为它应该很大。

您可以查看代码和程序here。如果我对任何事情不是很清楚,请告诉我,这个很难解释。

这是我前一段时间创建的片段,它添加了退出全屏的 esc 键功能。我希望它也对你有用。

$('#view-fullscreen').click(function(){

    $('#container').css({'background': '#000000'}).fullScreen({

        'callback'      : function(fullScreen){
            if ( !fullScreen ) {


                $('#container').css({'background': '#ffffff'});

            }
        }

    });

    $(this).hide();
    return false;


});

欢迎来到 fullscreen API 噩梦。

这个 API 仍在开发中,自从它首次出现在网络上以来,规格已经发生了很大变化。
不幸的是,截至今天,none 的主要浏览器确实支持它 (例如,实际规范建议使用 promises) 更糟糕的是,none请为此 API 使用相同的关键字。

所以让他们都满意可能有点苛刻。

但是首先,您不应该监听 resize 事件,因为它可能会在全屏模式 activation/desactivation 期间多次发生。

你需要的是fullscreenchange活动。
幸运的是,每个 UA 都写了完整的事件名称,其中没有任何驼峰式命名,但带有供应商前缀。 (出于某种原因,IE 不支持使用 addEventListener 方法附加它...)

一旦你得到这个事件,为了知道我们是否真的进入或退出了全屏模式,你必须检查 document.[vendor-prefix]full(s||S)creenElement 如果有,那么我们就进入了全屏模式;否则我们退出它。

现在,要退出全屏模式,您必须调用
document.[vendor-prefix]((e||E)xit||Cancel)(f||F)ull(s||S)creen 方法。

所以这里有一些 dirty 辅助函数:

// if fullscreen API is supported it will return an array containing
// [vendor-prefix, 'full(s||S)creen', 'Exit||Cancel'];
var fs = function(){
    // if it is natively supported without vendor prefix (may it happen some day...)
    if('onfullscreenchange' in document){
        return ['', 'Fullscreen', 'exit'];
    }
    if('onmozfullscreenchange' in document){
        return ['moz','FullScreen', 'Cancel'];
    }
    if('onwebkitfullscreenchange' in document){
        return ['webkit', 'Fullscreen', 'Exit'];
    }
    if('onmsfullscreenchange' in document){
        return ['ms', 'Fullscreen', 'Exit'];
    }
}();


if(fs){
    // for some reason, IE doesn't support the addEventListener method...
    document['on'+fs[0]+'fullscreenchange'] = function(){

        ctx.clearRect(0, 0, c.width, c.height);
        // check for 'fullscreenElement' to know weither we entered or exited the fullscreen mode
        var status = document[fs[0]+fs[1]+'Element'];

        var statusString =  status ? 'entered':'exited';
        ctx.fillText(statusString+' fullscreen', 250, 50);
        // increment our fullscreen change counter
        fs_count++;
        if(status){
            ctx.fillText('click the canvas to exit fullscreen mode', 150 , 100);
            // attach the exit/cancel fullscreen call
            c.onclick = function(){document[fs[0]+fs[2]+fs[1]]();};
            }
        // log the counters
        ctx.fillText('fullscreen calls : '+fs_count, 0, 140);
        ctx.fillText('resize calls : '+resize_count, 0, 150);
        };

    btn.onclick = function(){
        //this one implies a new camelCase if a vendor prefix is needed...
        var camel = fs[0] ? 'R':'r';
        c[fs[0]+camel+'equest'+fs[1]]();
    };
}
var ctx = c.getContext('2d');
ctx.fillStyle = "red";

var resize_count = 0;
var fs_count = 0;

// increment our resize counter
window.onresize= function(){resize_count++};
<canvas id="c" width="500"></canvas>
<button id="btn">enter fullscreen</button>

由于全屏请求在 iframe 中被阻止,您可以看到它的实际效果 here and play with the code here

此外,您会注意到每个浏览器对此请求的处理方式不同:webkit 浏览器将使页面全屏显示但保持元素的比例不变,而 FF 和 IE 会缩放元素以适应新页面尺寸。
这意味着您不应该查看 getBoundingClientRect() 矩形,而是根据 window.innerWidthwindow.innerHeight 属性计算新大小。