iOS 8 删除了“最小 ui”视口属性,还有其他“软全屏”解决方案吗?

(这是一个多部分的问题,我会尽力总结一下这个场景。

我们目前正在构建一个响应式Web应用程序(新闻阅读器),允许用户在选项卡式内容之间滑动,以及在每个选项卡式内容中垂直滚动。

解决此问题的一种常见方法是使用一个包装器来填充浏览器视区,将其设置为 或 ,然后在其中水平和/或垂直滚动。divoverflowhiddenauto

这种方法很棒,但有一个主要缺点:由于文档的高度与浏览器视口完全相同,因此移动浏览器不会隐藏地址栏/导航菜单

有许多黑客和视口属性使我们能够获得更多的屏幕空间,但没有一个像(在iOS 7.1中引入)那样有效。minimal-ui

昨天有消息称iOS 8 beta4已从Mobile Safari中删除(请参阅iOS 8发行说明中的Webkit部分),这让我们感到疑惑:minimal-ui

问题 1.是否仍然可以在移动野生动物园上隐藏地址栏?

据我们所知,iOS 7不再响应黑客攻击,这表明我们必须忍受较小的屏幕空间,除非我们采用垂直布局或使用 。window.scrollTomobile-web-app-capable

问题 2.是否仍有可能获得类似的软全屏体验?

通过软全屏,我真的意味着不使用元标记。mobile-web-app-capable

我们的Web应用程序是可访问的,任何页面都可以使用本机浏览器菜单添加书签或共享。通过添加,我们可以防止用户调用此类菜单(当它保存到主屏幕时),这会使用户感到困惑和对抗。mobile-web-app-capable

minimal-ui曾经是中间地带,默认情况下隐藏菜单,但通过点击即可保持可访问性 - 尽管Apple可能由于其他可访问性问题(例如用户不知道在哪里点击以激活菜单)而将其删除。

问题 3.全屏体验值得麻烦吗?

似乎全屏API不会很快进入iOS,但即使它是,我也不明白菜单将如何保持可访问性(Android上的Chrome也是如此)。

在这种情况下,也许我们应该保持移动野生动物园不变,并考虑视口高度(对于iPhone 5 +,它是460 = 568 - 108,其中108包括操作系统栏,地址栏和导航菜单; 对于iPhone 4或更早版本,它是372)。

很想听到一些替代方案(除了构建一个本机应用程序)。


答案 1

最小 ui 视口属性在 iOS 8 中不再受支持。但是,最小 ui 本身并没有消失。用户可以通过“向下触摸-拖动”手势输入最小 ui。

管理视图状态有几个前提条件和障碍,例如,为了使最小ui工作,必须有足够的内容使用户能够滚动;要使最小 ui 保持不变,必须在页面加载时和方向更改后偏移窗口滚动。但是,无法使用变量计算最小 ui 的维度,因此无法提前判断用户何时处于最小 ui 中。screen

这些观察结果是作为开发Brim - iOS 8视图管理器的一部分的研究结果。最终实现的工作方式如下:

加载页面后,Brim 将创建一个跑步机元素。跑步机元素用于为用户提供滚动空间。跑步机元素的存在可确保用户可以进入最小 ui 视图,并且在用户重新加载页面或更改设备方向时,该视图将继续保留。它始终对用户不可见。此元素具有 ID 。brim-treadmill

加载页面时或更改方向后,Brim 使用 Scream 来检测页面是否位于最小 ui 视图中(如果内容高度大于视口高度,则以前处于 minimal-ui 中并已重新加载的页面将保留在最小 ui 中)。

当页面位于最小ui中时,Brim将禁用文档的滚动(它以不影响主元素内容的安全方式执行此操作)。禁用文档滚动可防止在向上滚动时意外离开最小 UI。根据原始的iOS 7.1规范,点击顶部栏会带回Chrome的其余部分。

最终结果如下所示:

Brim in iOS simulator.

为了便于文档编写,如果您更喜欢编写自己的实现,值得注意的是,在方向更改事件之后,您无法使用 Scream 来检测设备是否处于最小 ui 中,因为在旋转动画结束之前,尺寸不会反映新方向。您必须将侦听器附加到方向更改事件window

Scream定向变化已经作为该项目的一部分进行了开发。


答案 2

由于没有编程方法来模仿 ,因此我们提出了一种不同的解决方法,使用和已知的iOS地址栏高度对我们有利:minimal-uicalc()

以下演示页面(也可在要点上找到,更多技术细节)将提示用户滚动,然后触发软全屏(隐藏地址栏/菜单),其中标题和内容填充新视口。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }

        html {
            background-color: red;
        }

        body {
            background-color: blue;
            margin: 0;
        }

        div.header {
            width: 100%;
            height: 40px;
            background-color: green;
            overflow: hidden;
        }

        div.content {
            height: 100%;
            height: calc(100% - 40px);
            width: 100%;
            background-color: purple;
            overflow: hidden;
        }

        div.cover {
            position: absolute;
            top: 0;
            left: 0;
            z-index: 100;
            width: 100%;
            height: 100%;
            overflow: hidden;
            background-color: rgba(0, 0, 0, 0.5);
            color: #fff;
            display: none;
        }

        @media screen and (width: 320px) {
            html {
                height: calc(100% + 72px);
            }

            div.cover {
                display: block;
            }
        }
    </style>
    <script>
        var timeout;

        window.addEventListener('scroll', function(ev) {

            if (timeout) {
                clearTimeout(timeout);
            }

            timeout = setTimeout(function() {

                if (window.scrollY > 0) {
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';
                }

            }, 200);

        });
    </script>
</head>
<body>

    <div class="header">
        <p>header</p>
    </div>
    <div class="content">
        <p>content</p>
    </div>
    <div class="cover">
        <p>scroll to soft fullscreen</p>
    </div>

</body>
</html>