首页 > 解决方案 > requestFullscreen 在消息事件处理程序中不再起作用

问题描述

用户单击一个按钮,然后在click事件处理程序中我们postMessage到 iframe。iframe 在message事件处理程序中处理它并调用element.requestFullscreen(). 在较旧的浏览器中它可以工作(例如在 Chrome 65 中),但在当前(72)中它会出现Failed to execute 'requestFullscreen' on 'Element': API can only be initiated by a user gesture..

有没有办法在postMessage通话中转移“手势启动”标志?

请注意,iframe 具有allow="fullscreen"属性。

标签: google-chromefirefoxpostmessagehtml5-fullscreen

解决方案


与 iframe 一样,它取决于这里它是相对于父文档托管的。

如果您在该框架中运行同源文档,那么您可以简单地requestFullScreen直接调用您希望形成主文档的元素:

const frameDoc = frame.contentDocument;
frameDoc.getElementById('el-to-fs').requestFullscreen(); // assuming polyfill

jsfiddle 由于 StackSnippets® 过度保护的 iframe 将不允许访问或全屏。


但如果你是,你不会在 Chrome 中遇到这个问题(你仍然会在 FF 中遇到)。

因为即使这种方法确实需要用户手势postMessage并且速度足够快,您也可以在 Chrome 中将其与同源框架一起使用。

在此浏览器中发生的情况是,跨域文档必须先收到用户手势,然后才能调用requestFullscreen.
一旦跨域框架被标记为由用户交互,那么您requestFullscreen甚至可以从主文档的事件中调用:jsfiddle(仍然,仅在 Chrome 中)。

但是,对于跨浏览器解决方案,您必须

  • 将此内容加载为同源(例如使用代理)
  • 或者使用一个小技巧,<iframe>在全屏模式下设置并让内部文档知道您这样做了,因此它可以相应地设置其文档的样式:jsfiddle
    main.js

    onclick = e => {
      frame.contentWindow.postMessage("you're going fullscreen", '*');
      frame.requestFullscreen();
    };
    

    框架.js

    onmessage = e => {
      if(message.data === "you're going fullscreen") {
        // trigger our special fullscreen CSS
        document.documentElement.classList.add('fullscreen');
        // do some DOM cleaning if needed
      }
      else if(message.data === "you're exiting fullscreen") {
        document.documentElement.classList.remove('fullscreen');
      }
    };
    

推荐阅读