如何禁止 iFrame 滚动其父级 window?

How do I forbid an iFrame from scrolling its parent window?

我有一个 HTML 文档,其底部包含一个 iframe。

在这种情况下,iframe 嵌入了一个 Google 电子表格,代码为:

<iframe id="gsheet-group" width="100%" height="400" src="https://docs.google.com/spreadsheets/d/<!----DOCUMENT_KEY----->/edit?usp=sharing&rm=minimal&gid=0&single=true&widget=false&chrome=false&headers=false">Loading sheet..</iframe>

我认为此 iframe 包含一些 javascript 会导致其在某些事件上 parent window to scroll to the top,例如加载完成或以特定方式导航其内容时。 (如果 iframe 嵌入到第二个 iframe 中,此行为仍然存在。)

如果我不能直接修改 iframe 的源代码,我可以防止父 window 在 iframe 嵌入的内容中被 javascript 操纵吗?

我试过的

感谢评论者的建议,none不幸解决了问题:

API 甚至 cross-origin iframe 都可以滚动顶部文档的 Element#scrollIntoView()。我没有检查它是否真的是您的嵌入式页面在做什么,但这听起来像是一个非常合理的解释。

这是一个最小的例子。重现:

  • 运行 片段
  • 立即手动滚动到页面顶部。
  • 等待大约 2 秒,让代码片段自动回滚查看:

(也可以在结果iframe中点击再次调用scrollIntoView,2s后)

onclick = e => setTimeout(() => {
  document.body.scrollIntoView();
}, 2000);
onclick();
Scroll to the top of the top page and wait 2s.

在深入研究规范后,恐怕没有 out-of-the-box 解决方案来防止这种行为...
一件值得注意的事情是 Chrome will not scroll to fixed elements in an iframe。这意味着我们实际上可以 hack-around 这个 bug 来定义一个“scroll-stop”层:你可以将目标 iframe 包裹在另一个 iframe 中,设置这个内部 iframe 的位置固定,以便它完全覆盖包装 iframe。这将阻止 Chrome 滚动此 iframe 的祖先:

iframe { position: fixed; top: 0; width: 100vw; height: 100vh; border: none; padding: 0; margin: 0; }
<iframe srcdoc="
<script>
  onclick = e => setTimeout(() => {
    document.querySelector('h1').scrollIntoView();
  }, 2000);
  onclick();
</script>
<h1 style='margin-top: 100vh' >I still scroll into view, but not the top page.</h1>
"></iframe>

然而这是一个完整的hack-around,它基本上是一个漏洞利用,显然在其他web-browsers中不起作用,甚至可能在Chrome的未来版本中失败,如果他们解决了问题。
但这是我目前唯一能找到的东西。

不过,我邀请您做的是在 W3C's CSS working group's Github repo 上提出您的观点,以便他们考虑添加一个 属性 以正式允许此功能。

在遵循@Kaiido 的建议在 W3C 跟进之后,那里的评论确认当前标准确实不支持所需的行为。如果接受,proposal 将允许通过以下方式禁用垂直滚动:

<iframe src="..." allow="vertical-scroll 'none'"></iframe>

可以跟踪提案的状态here