0

我正在使用window.matchMedia. 以下代码按预期工作 - 每个方向更改都以正确的值记录到控制台:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Test App</title>
  </head>
  <body>
    <script type="application/javascript">
        let isIframe= () => {
            try {
                return window.self !== window.top;
            } catch (e) {
                return true;
            }
        }    

         let onOrientationChange = () => {
            const isLandscape = window.matchMedia("(orientation: landscape)").matches;
            console.log("Event: " + (isIframe() ? "Iframe " : "") + "landscape:" + isLandscape);
        }

        let mediaQueryList = window.matchMedia("(orientation: landscape)");
        
        console.log("Onload: " + (isIframe() ? "Iframe " : "") + "landscape:" + mediaQueryList.matches);

        mediaQueryList.addListener(onOrientationChange);
    </script>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root">Hello World in Iframe</div>
  </body>
</html>

但是当我在 中运行该页面时,不会触发iframe使用注册的回调。addListeneriframe中,我只得到单数日志行 - Onload: Iframe landscape:true,无论设备方向如何。

 <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root">Hello World</div>
    <iframe id="game" src="iframeContent.html" frameborder="0" style="width: 960px; height: 600px;"></iframe>
  </body>

我使用addListener而不是addEventListener,因为第二个功能不适用于所有 Safari 版本。

在 Safari 14 以及 Chrome 和 Firefox 的开发工具上测试。

我的问题是 - 为什么addListener没有在iframe.

谢谢你。

4

1 回答 1

1

如果 iframe 没有改变它的大小,因为它具有固定的宽度和高度,则无法在其中触发调整大小相关的事件,包括MediaQueryList有关orientation.

你可以做两件事来让它工作;您可以将 iFrame 宽度和高度设置为100%,或者您可以让媒体查询检测代码在主窗口内,并postMessage在触发更改事件时使用它传递方向状态。

1) 更改 iFrame 大小,100%以便在横向/纵向事件触发时调整大小

在主页中,使正文全高和 iframe 全宽/高(使用 CSS)。

body {
  height: 100vh;
  margin: 0;
}

iframe {
  width: 100%;
  height: 100%;
}

您可以测试的实时示例:https ://zikro.gr/dbg/so/65704468/

2) 主页上的媒体查询检测,用于postMessage在orientation事件触发时向iFrame发送消息

index.html

<iframe src="iframe.html"></iframe>
<script>
  let iframe = document.querySelector('iframe');

  let onOrientationChange = () => {
    iframe.contentWindow.postMessage({
      isLandscape: window.matchMedia("(orientation: landscape)").matches
    }, '*');
  }

  iframe.addEventListener('load', onOrientationChange);

  const mediaQueryList = window.matchMedia("(orientation: landscape)");

  mediaQueryList.addListener(onOrientationChange);
</script>

iframe.html

<script>
  window.addEventListener("message", (event) => {
    if (event.data.isLandscape) {
      console.log('iFrame Landscape');
    } else {
      console.log('iFrame Portrait');
    }
  });
</script>

您可以测试的实时示例:https ://zikro.gr/dbg/so/65704468/pm/

于 2021-01-16T12:09:27.303 回答