[英]window.matchMedia not works in iframe
I'm detecting device orientation using window.matchMedia
.我正在使用
window.matchMedia
检测设备方向。 The following code works as intended - every orientation change is logged to console with correct value:以下代码按预期工作 - 每个方向更改都以正确的值记录到控制台:
<!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>
But when I run that page in iframe
, callback registered using addListener
is not fired.但是当我在
iframe
中运行该页面时,不会触发使用addListener
注册的回调。 In iframe
, I only get singular log line - Onload: Iframe landscape:true
, regardless of the device orientation.在
iframe
中,我只得到单数日志行 - 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>
I'm using addListener
instead of addEventListener
, because the second one function is not working on all Safari versions.我正在使用
addListener
而不是addEventListener
,因为第二个 function 不适用于所有 Safari 版本。
Tested on Safari 14 and on Dev Tools of Chrome and Firefox.在 Safari 14 以及 Chrome 和 Firefox 的开发工具上进行了测试。
My question is - why addListener
callback is not invoked in iframe
.我的问题是 - 为什么在
iframe
中没有调用addListener
回调。
Thank you.谢谢你。
If the iframe does not get it's size to change because it has fixed width and height, thus resize related events cannot be triggered inside it includingMediaQueryList
events regarding orientation
.如果 iframe 没有改变它的大小,因为它具有固定的宽度和高度,因此无法在其中触发调整大小相关事件,包括有关
orientation
的MediaQueryList
事件。
You can do two things to get this working;你可以做两件事来让它工作; you can make your iFrame width and height to be
100%
, or you can let the media query detection code inside the main window and pass the orientation state using postMessage
when it triggers a change event.您可以使您的 iFrame 宽度和高度为
100%
,或者您可以让主 window 内的媒体查询检测代码并传递方向postMessage
当它触发 change 事件时。
100%
so it resizes when landscape/portrait orientation event triggers 100%
,以便在横向/纵向方向事件触发时调整大小In the main page, make the body full height and the iframe full width/height (using CSS).在主页中,使主体全高和 iframe 全宽/高(使用 CSS)。
body {
height: 100vh;
margin: 0;
}
iframe {
width: 100%;
height: 100%;
}
Live example that you can test: https://zikro.gr/dbg/so/65704468/您可以测试的实时示例: https://zikro.gr/dbg/so/65704468/
postMessage
to send a message to iFrame when orientation event triggers postMessage
向iFrame发送消息index.html
: 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
: iframe.html
:<script>
window.addEventListener("message", (event) => {
if (event.data.isLandscape) {
console.log('iFrame Landscape');
} else {
console.log('iFrame Portrait');
}
});
</script>
Live example that you can test: https://zikro.gr/dbg/so/65704468/pm/您可以测试的实时示例: https://zikro.gr/dbg/so/65704468/pm/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.