提问者:小点点

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


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

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

解决此问题的常用方法是使用包装器div填充浏览器视口,将overflow设置为hiddedauto,然后在其中水平和/或垂直滚动。

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

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

昨天传来消息,iOS 8 beta4已经从Mobile Safari中删除了minimal-UI(参见iOS 8发行说明中的Webkit部分),这让我们很疑惑:

Q1.移动Safari上还有可能隐藏地址栏吗?

据我们所知,iOS7不再响应window.scrollto黑客攻击,这意味着我们必须与更小的屏幕空间一起生活,除非我们采用垂直布局或使用mobile-web-app-cable

Q2.还能有类似的软全屏体验吗?

所谓软全屏,我真正的意思是不使用mobile-web-app-cable元标记。

我们的web应用程序是建立为可访问的,任何页面都可以被书签或共享使用本机浏览器菜单。通过添加mobile-web-app-cable,我们可以防止用户调用这样的菜单(当它保存到主页时),这会使用户感到困惑和反感。

minimal-ui曾经是一种折衷的方法,默认情况下隐藏菜单,但通过轻击保持它的可访问性--尽管苹果可能会出于其他可访问性考虑(比如用户不知道在哪里点击才能激活菜单)而将其删除。

Q3.全屏体验值得这么麻烦吗?

似乎全屏API不会很快出现在iOS上,但即使真的出现了,我也不知道该如何保持菜单的可访问性(Android上的Chrome也是如此)。

在这种情况下,也许我们应该让mobile safari保持原样,并考虑视口高度(对于iPhone5+,视口高度为460=568-108,其中108包括操作系统栏、地址栏和导航菜单;对于iPhone4或更高版本,视口高度为372)。

希望听到一些替代方案(除了构建一个原生应用程序)。


共2个答案

匿名用户

iOS 8不再支持minimal-ui视口属性。然而,最小UI本身并没有消失。用户可以通过“触摸-拖动”手势进入最小界面。

管理视图状态有几个前提条件和障碍,例如,要使最小UI工作,必须有足够的内容使用户能够滚动;要使minimal-ui持久存在,必须在页面加载时和方向更改后偏移窗口滚动。但是,无法使用screen变量计算最小UI的尺寸,因此无法预先告知用户何时在最小UI中。

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

加载page时,Brim将创建一个treadmill元素。Treadmill元素用于为用户提供滚动的空间。treadmill元素的存在确保用户可以进入最小UI视图,并且如果用户重新加载页面或更改设备方向,它将继续保持。它对用户来说是不可见的。此元素的ID为brim-treadmill

加载页面或改变方向后,Brim使用尖叫来检测页面是否在最小UI视图中(如果内容高度大于视口高度,则先前在最小UI中并重新加载的页面将保留在最小UI中)。

当page在minimal-ui中时,Brim将禁用文档的滚动(它以一种不影响主元素内容的安全方式执行此操作)。禁用文档滚动可防止向上滚动时意外离开最小UI。按照最初的iOS7.1规范,点击顶部条将恢复Chrome的其余部分。

最终结果看起来是这样的:

出于文档的考虑,并且如果您更愿意编写自己的实现,值得注意的是,您不能在orientationchange事件之后直接使用尖叫来检测设备是否处于最小UI中,因为window维度在旋转动画结束之前不会反映新的方向。必须将侦听器附加到orientationchangeend事件。

Scream和orientationchangeend已作为该项目的一部分开发。

匿名用户

由于没有编程方法来模拟minimal-UI,我们提出了一个不同的解决方案,使用calc()和已知的iOS地址栏高度,这对我们有利:

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

<!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>