在iOS浏览器中,当在iFrame中引用时,'deviceorientation'事件无法触发

3
我正在制作一个网站,在iframe中运行“360全景查看器”,源页面使用JavaScript和window.DeviceOrientationEvent来确定用户是否在具有方向功能的移动设备上。我在iOS Safari和Chrome上看到一些奇怪的行为:

window.DeviceOrientationEvent计算结果为true,但deviceorientation事件从未触发。

这在Android Chrome上不是这种情况-当在iFrame中使用时,事件会按预期连续触发。
当直接访问页面(在iOS上)时,我看到事件触发。就像在iframe中使用它会以某种方式“阻止”此事件一样。
这对我来说没有多大意义,研究它只能发现一些模糊的信息[1,2],表明它实际上可能与CORS有关-无论iframe源是否与父页面在同一根域上。这对我来说甚至更没有意义。
有人有线索吗?

{{链接1:1}} {{链接2:2}}


iFrame是否与父页面位于同一根域名下? - beyowulf
1
不行 - 这就是问题所在。iframe内容存储在S3桶中,用于主Web应用程序的静态资源。 - Aksel Gresvig
3个回答

6

对于现在遇到这个问题的任何人来说,似乎自从iOS 12.2以后,Apple已经禁用了deviceorientation API。现在用户需要明确地在设置 > Safari > 运动和方向访问中切换它。有关讨论,请参见此处


有人知道是否有一种方法可以检测这个标志是否为false吗?'DeviceMotionEvent'和'DeviceOrientatinonEvent'仍然评估为true。 - James P
@JamesP 如果我按照我的答案中链接的 Github 线程,目前唯一的方法是通过轮询事件本身来实现。 - Husky

3
这可以通过使用Window.postMessage()来向iframe传递信息来解决。但是,您需要访问两个网站:父级和iframe。首先在父级中监听deviceorientation事件,然后使用postMessage将其传递到iframe中。
// Parent
window.addEventListener("deviceorientation", function (event) {
let iframeElement = document.getElementById("my-iframe");
iframeElement.contentWindow.postMessage({
        alpha: event.alpha,
        beta: event.beta,
        gamma: event.gamma
    },
    "*"
);
// Child
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
    console.debug(event.data);
}

这就是8th Wall在他们的自定义实现中的做法,例如。虽然这是可能的,但似乎比仅此更复杂。 - Kyle Baker

2

对于任何感兴趣的人,我已经验证了问题是由于跨域资源共享(CORS)引起的。苹果公司会阻止在 iframe 中使用页面事件,这应该是一项安全措施。

我的临时解决方案是将文件托管在同一服务器上,但这并不是可扩展的解决方案,因此我认为我需要设置某种代理来处理这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接