在全页 iframe 中向下滚动时隐藏移动设备上的地址栏

问题描述 投票:0回答:1

问题:

当您在移动设备上向下滚动页面时,某些浏览器会启发式隐藏浏览器地址栏。这很好,因为它“免费”提供了更多的屏幕空间。用户可以向上滚动一点以再次显示地址栏。

我有一种情况,我嵌入的 iframe 占据了整个页面,除了属于父框架的标题栏。为了沙箱用户编写的代码(类似于 CodePen/JSBin/等),这是必要的。我希望当用户在 iframe 内向下滚动时隐藏浏览器地址栏。

额外背景

  • 我控制着顶层页面,可以将代码注入嵌入式 iframe 并通过
    postMessage
    进行通信。
  • 我愿意对我的解决方案(例如,在帧之间涉及
    postMessage
    )进行一些修改,如果它会导致最终结果相当稳健 - 即不太可能随机中断滚动/在某些浏览器中,在某些情况下条件(例如用户捏合缩放页面),或在对启发式进行一些有效更新后等。如果它在某些浏览器中工作,但自动/安全地回退到在不受支持的情况下没有任何影响,那么就可以了。
  • iframe 中的任何“干预”都不应该以可能与绝大多数 Web 应用程序相关的方式干扰用户代码。例如。向父级发送
    postMessage
    就可以了,因为它不太可能干扰用户代码。
  • 可能不相关,iframe 是通过
    Origin-Agent-Cluster
    进行线程/性能隔离的。而且这两个框架有不同的起源。

非解决方案:

  • 使 iframe 与其内容一样高并不是解决方案,因为这会导致视觉视口大小异常,从而影响用户代码,例如在视觉上将其内容集中在视口中,或依赖于
    window.innerHeight
    (和 CSS
    vh
    )等属性进行计算。
  • 添加全屏按钮不是解决方案,但它确实提供了一种适合某些用例的替代方案。
  • 在顶层运行用户代码(具有自己的子域)不是一个解决方案,因为我需要父框架来实现重要的平台级功能。

尝试的解决方案:

考虑到我上面概述的一系列要求,我对目前实现这一目标并不乐观。

  1. 我的第一个想法是,我可以以编程方式与子框架同步滚动顶级框架(使用子框架中的

    postMessage
    ),这样当他们滚动子框架时,地址栏就会自然地隐藏自己足够远了。但不幸的是(至少在 Android Chrome 中),用户代理不会基于编程滚动隐藏地址栏 - 可能是出于安全/反欺骗的原因。

  2. 我的第二个想法是,我必须告诉嵌入式 iframe 将

    overflow:hidden;
    设置为
    document.scrollingElement
    ,以便过度滚动触发父框架滚动,从而触发用户代理隐藏地址栏,然后也许我可以使用 Visual Viewport API 检测到这一点,并告诉 iframe 重新启用滚动。即使这可行,这也肯定会突破“不干扰用户代码”规则的极限。理想情况下,由 parent 决定 iframe 在地址栏消失之前不可滚动。但还存在一个问题,即知道地址栏是否真的会消失,以及何时它会开始消失,因为我不认为地址栏隐藏会立即发生 - 这使事情变得更加复杂。

所以,看起来你需要一些极其的黑客才能让它工作。我希望最终有一种浏览器标准支持的方法来做到这一点,尽管我相当悲观,但我发布这个问题的部分原因是这样我希望在它成为可能时得到通知。

javascript html google-chrome iframe viewport
1个回答
0
投票

如果我的说法正确,您需要禁用 iframe 滚动,直到页面向上滚动到足以从页面中删除浏览器镶边为止。

我的建议是在 iframe 上设置

scrolling=“no”
属性,然后通过
onScroll
事件和 VisualViewport API 观察页面,以检测页面何时滚动得足够多。您可以在 iframe 上设置
scrolling=“auto”
或将其删除。

从技术上讲,滚动属性在十多年前就已被弃用,但 CSS 工作领域仍然没有时间实现相同的功能,并且所有现代浏览器仍然乐意支持它。

© www.soinside.com 2019 - 2024. All rights reserved.