iOS 8删除了“ minimum-ui”视口属性,是否还有其他“软全屏”解决方案?


191

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

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

解决该问题的常用方法是使用一个包装器div来填充浏览器视口,将其设置overflowhiddenauto,然后在其中进行水平和/或垂直滚动​​。

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

许多hack和视口属性可以使我们获得更多的屏幕空间,但效果却不如minimal-uiiOS 7.1中引入的效果。

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

Q1。是否仍然可以在Mobile Safari中隐藏地址栏?

据我们所知,iOS 7 不再对这种window.scrollTo入侵做出响应,这表明我们必须使用较小的屏幕空间,除非我们采用垂直布局或使用mobile-web-app-capable

Q2。是否仍有可能获得类似的软全屏体验?

通过软全屏,我的意思是不使用mobile-web-app-capablemeta标签。

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

minimal-ui过去是中间地带,默认情况下隐藏菜单,但可通过轻按使其保持可访问状态 -尽管Apple可能由于其他可访问性问题(例如用户不知道在何处激活菜单)而将其删除。

Q3。全屏体验值得麻烦吗?

似乎全屏API不会很快进入iOS,但是即使这样,我也看不到菜单如何保持可访问性(Android上的Chrome也是一样)。

在这种情况下,也许我们应该只保留移动浏览器,并考虑视口高度(对于iPhone 5+,它是460 = 568-108,其中108包括OS栏,地址栏和导航菜单;对于iPhone 4或更老的是372)。

很想听听其他选择(除了构建本机应用程序之外)。


请参阅stackoverflow.com/questions/18793072/…,以了解有关为什么最小用户界面对于某些应用程序至关重要的更多详细信息。
bitinn 2014年

1
我在iOS 7上遇到了同样的问题,因为我们正在尝试构建带有滑动/滚动事件的Web应用程序,但是在iOS8 Beta 4和..上测试了onScroll事件,它们可以工作。ios8-scroll-events.heroku.com 不确定是否有帮助,但是..您有想要的。
Devin McInnis 2014年

遇到同样的麻烦。目前只有javascript“修复”,如下面的calc()函数是唯一的答案。如果您知道更好的决定,请保持此线程更新。最好的祝福。
A1exandr 2014年

Answers:


86

iOS 8 不再支持 minimal-ui视口属性。但是,μm-ui本身并未消失。用户可以通过“触摸拖动”手势输入最小用户界面。

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

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

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

加载页面或更改方向后,Brim正在使用 Scream来检测页面是否处于“最小用户界面”视图中(如果内容高度为,则先前已处于“最小用户界面”中且已重新加载的页面将保留在“最小用户界面”中)。大于视口高度)。

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

最终结果如下所示:

iOS模拟器中的边缘。

为方便说明起见,并且如果您更愿意编写自己的实现,则值得注意的是,您不能使用Scream来检测定向更改事件后设备是否处于最小用户界面,因为window尺寸直到旋转动画已结束。您必须将侦听器附加到directionchangeend事件。

尖叫方向改变已作为该项目的一部分开发。


3
这比我原来的答案更宽敞,在获得更好的解决方案之前将其标记为新答案:)
bitinn

4
看上去不错!我可以在没有初始滚动的情况下强制使用最小用户界面吗?
INT

50
这确实是永无止境的故事。我是使用HTML的游戏开发人员,而iOS 7.1中的minimal-ui则运行良好-这是使应用程序全屏运行并同时能够在屏幕底部进行触摸的唯一方法。与网页刷卡解决方案都不错,但还不够好:(苹果,我们需要全屏API的游戏的正确实施,请。
切赫城市

3
@Petr:我完全同意。在7.1中宣布此修复程序后,我们迅速推出了新的结帐购买流程,该流程将主要CTA固定在了屏幕的底部。感觉非常“原生”且无缝。我认为这是确切的问题。如果您考虑一下,让Web应用程序看起来像本地软件并不符合Apple的最大利益。实际上,这与他们在App Store中的垄断直接存在利益冲突。这是IMO唯一有效的理由,它确定了具有如此重要意义的功能,然后有意将其删除。#my2Cents :)
何塞·布朗

2
@PetrUrban我坚信Apple宁愿您将游戏发布为phonegap应用程序,也不希望您通过网络提供服务。他们最近决定允许广告拦截器用于野生动物园巩固了这一想法。
Patrick Gunderson 2015年

20

由于没有模仿的编程方式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>

10

只需向Minimum-ui说再见(目前)

的确如此,minimal-ui既有用又有害,而且我认为这种权衡现在又有一个平衡点,支持更新,更大的iPhone。

在处理HTML5应用程序的js框架时,我一直在处理该问题。在尝试了许多解决方案(每种都有其缺点)之后,我屈服于考虑iPhone上6之前的空间损失。考虑到这种情况,我认为唯一可预见的行为是预定的行为。

简而言之,我最终阻止了任何形式的minimal-ui,因此至少我的屏幕高度始终是相同的,并且您始终知道应用程序的实际空间。

在时间的帮助下,足够多的用户将有更多的空间。


编辑

我该怎么做

出于演示目的,对此进行了一些简化,但是应该为您工作。假设您有一个主容器

html, body, #main {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
.view {
  width: 100%;
  height: 100%;
  overflow: scroll;
}

然后:

  1. 然后使用js,将#main的高度设置为窗口的可用高度。这也有助于处理iOS和Android中发现的其他滚动错误。这也意味着您需要处理如何更新它,只需注意;

  2. 达到滚动范围时,我会阻止过度滚动。这一点在我的代码中更加深入,但是我认为您也可以遵循此答案的基本功能。我认为这可能会稍作调整,但会完成任务。


观看演示(在iPhone上)

附带说明:该应用程序也可添加书签,因为它使用内部路由来哈希地址,但我还添加了一个提示iOS用户将其添加到首页。我觉得这种方式有助于忠诚度和回头客(因此,失去的空间又回来了)。


禁用最小用户界面对我来说似乎很合理。请提供简短说明,以说明如何执行此操作!
伊什特万Pálinkás

没错,我添加了一些操作方法。许多其他方式也可以使用。
Francesco Frapporti 2014年

1
您的演示不能在iOS8上工作的,按照我的iPhone 5
dmr07

感谢您让我知道,因为它曾经可以正常工作,所以必须进行一些更新。你在野生动物园吗?您完全不知道这是什么意思?
Francesco Frapporti 2015年

7

我发现解决此问题的最简单方法是将用户代理为iPhone的任何请求的主体和html元素的高度设置为100.1%。这仅在横向模式下有效,仅此而已。

html.iphone, 
html.iphone body { height: 100.1%; }

https://www.360jungle.com/virtual-tour/25上查看


谢谢@斯蒂芬。身高:100.1%帮助了我。但是,当我在iPhone(iOS 11.1.1)Safari上打开360jungle.com/virtual-tour/25并单击底部的按钮时,将显示地址和工具栏。这是因为按钮离显示结尾太近了。我想最好将它们移动到其他位置。
TEWA

2

根本问题在于,如果内容等于或小于视口,则向下滚动时,iOS8野生动物园不会隐藏地址栏。

如您所知,在底部添加一些填充可解决此问题:

html {
    /* enough space to scroll up to get fullscreen on iOS8 */
    padding-bottom: 80px;
}
// sort of emulate safari's "bounce back to top" scroll
window.addEventListener('scroll', function(ev) {
    // avoids scrolling when the focused element is e.g. an input
    if (
        !document.activeElement
        || document.activeElement === document.body
    ) {
        document.body.scrollIntoViewIfNeeded(true);
    }
});

上面的CSS应该有条件地应用,例如UA嗅探将gt-ios8类添加到<html>


1
这个JS到底做什么?
Ben Sinclair 2014年

如果您指的是scrollIntoViewIfNeeded,则是scrollIntoViewdeveloper.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView)的非标准派生。顾名思义,该方法将元素滚动到视图中。true参数表示将视图与元素的顶部对齐。这实际上应防止您滚动。但是,该实现存在缺陷。
Gajus 2014年

1

我想发表评论/部分回答/分享我的想法。我正在将overflow-y:scroll技术用于我的一个大型项目。使用它有两个主要优点。

a)您可以使用屏幕底部带有操作按钮的抽屉;如果文档滚动并且底部栏消失,则点击位于屏幕底部的按钮将首先使底部栏出现,然后可以单击。而且,这种方法的工作方式会导致在最底部具有按钮的模态产生麻烦。

b)当使用溢出元素时,在css发生重大更改的情况下,唯一可以重绘的内容是可见屏幕中的内容。当使用javascript动态更改多个元素的css时,这极大地提高了我的性能。例如,如果有一个包含20个元素的列表,则需要重新绘制,而在溢出的元素中只有两个在屏幕上显示,滚动时仅重新绘制,而其余则重新绘制。没有它,所有20个元素都会重新粉刷。

..当然,这取决于项目以及您是否需要我提到的任何功能。Google使用gmail溢出元素来使用我在a)中描述的功能。Imo,即使考虑到旧版iPhone的高度较小(如您所说的372px),也值得一试。


1

可能是这样,使用下面的示例,我将其与(https://gist.github.com/bitinn/1700068a276fb29740a7)中在iOS 11上无法正常工作:

这是在iOS 11.03上运行的修改后的代码,如果适用于您,请发表评论。

关键是给BODY添加一些大小,以便浏览器可以滚动,例如:height:calc(100%+ 40px);

下面的完整示例和链接可在浏览器中查看(请测试!)

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CodeHots iOS WebApp Minimal UI via Scroll Test</title>

    <style>
        html, body {
            height: 100%;
        }
        html {
            background-color: red;
        }
        body {
            background-color: blue;
            /* important to allow page to scroll */
            height: calc(100% + 40px);
            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;

        function interceptTouchMove(){
            // and disable the touchmove features 
            window.addEventListener("touchmove", (event)=>{
                if (!event.target.classList.contains('scrollable')) {
                    // no more scrolling
                    event.preventDefault();
                }
            }, false); 
        }

        function scrollDetect(event){
            // wait for the result to settle
            if( timeout ) clearTimeout(timeout);

            timeout = setTimeout(function() {
                console.log( 'scrolled up detected..' );
                if (window.scrollY > 35) {
                    console.log( ' .. moved up enough to go into minimal UI mode. cover off and locking touchmove!');
                    // hide the fixed scroll-cover
                    var cover = document.querySelector('div.cover');
                    cover.style.display = 'none';

                    // push back down to designated start-point. (as it sometimes overscrolls (this is jQuery implementation I used))
                    window.scrollY = 40;

                    // and disable the touchmove features 
                    interceptTouchMove();

                    // turn off scroll checker
                    window.removeEventListener('scroll', scrollDetect );                
                }
            }, 200);            
        }

        // listen to scroll to know when in minimal-ui mode.
        window.addEventListener('scroll', scrollDetect, false );
    </script>
</head>
<body>

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

</body>

完整的示例链接在这里:https : //repos.codehot.tech/misc/ios-webapp-example2.html



-2

我还没有针对iOS进行网页设计,但是据我回想起在WWDC会话和文档中看到的那样,Mobile Safari中的搜索栏以及整个OS上的导航栏现在将自动调整大小并缩小以显示更多内容。

您可以在iPhone上的Safari中对此进行测试,请注意,当您向下滚动以查看页面上的更多内容时,导航/搜索栏将自动隐藏。

最好还是保留地址栏/导航栏,而不创建全屏体验。我看不到苹果很快就会这样做。而且最多它们不会自动控制何时显示/隐藏地址栏。

当然,您正在失去屏幕空间,尤其是在iPhone 4或4S上,但是从Beta 4开始似乎没有其他选择。


1
我知道iOS7 +的这一功能,但请参见上面的解释:由于文档的高度与浏览器视口完全相同,因此移动浏览器将不会隐藏地址栏/导航菜单,因为在文档级没有滚动。
bitinn 2014年

1
由于Beta 4删除了该功能,因此这可能是一个限制。Apple可能会自动控制地址栏,并阻止开发人员访问它。
iFeli 2014年

8
I haven't done web design for iOS-如果您要进行网页设计,则可以在每个平台上进行。因为网络在每个平台上都有。
ProblemsSuSumit

4
@Sumit我知道在Web上工作是通用的,但是每个浏览器及其底层框架都有特定的CSS属性。因此,Chrome可能具有Safari和FireFox无法使用的某些属性,反之亦然。
iFeli 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.