iOS 8删除了“minimal-ui”视口属性,还有其他“软全屏”解决scheme吗?

(这是一个多部分的问题,我会尽我所能来总结情况。)

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

解决这个问题的一个常见方法是使用一个包装器div来填充浏览器视口,将overflow设置为hiddenauto ,然后在其内部水平和/或垂直滚动​​。

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

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

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

Q1。 是否仍然可以隐藏移动Safari的地址栏?

据我们所知,iOS 7 不再响应 window.scrollTo hack,这意味着除非我们采用垂直布局或使用支持mobile-web-app-capable ,否则我们不得不使用较小的屏幕空间。

Q2。 还有可能有一个类似的软全屏体验?

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

我们的networking应用程序构build为可访问的,任何页面都可以使用本机浏览器菜单添加书签或共享。 通过添加mobile-web-app-capable我们阻止用户调用这个菜单(当它被保存到主屏幕),这迷惑和对抗用户。

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

Q3。 是一个全屏幕的经验值得麻烦?

看起来, 全屏API不会很快来到iOS,但即使是这样,我也不会看到菜单如何保持可访问(Android上的Chrome也是如此)。

在这种情况下,也许我们应该只保留移动Safari浏览器,并考虑视口高度(对于iPhone 5+,它是460 = 568 – 108,其中108包括操作系统栏,地址栏和导航菜单; iPhone 4或年纪大了,372)。

很想听到一些替代品(除了build立一个本地的应用程序)。

minimal-ui viewport属性在iOS 8中不再支持 。但是,minimal-ui本身并没有消失。 用户可以通过“触摸下拉”手势inputminimal-ui。

pipe理视图状态有几个先决条件和障碍,例如为了最小化UI工作,必须有足够的内容来使用户滚动; 为了保持最小UI,窗口滚动必须在页面加载和方向改变之后偏移。 然而,使用screenvariables计算最小用户界面的尺寸是没有办法的 ,因此没有办法预先知道用户何时处于最小用户界面。

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

页面加载后,Brim将创build一个跑步机元素。 跑步机元素用于给用户滚动的空间。 跑步机元件的存在确保用户可以进入最小UI视图,并且如果用户重新加载页面或改变设备方向,则持续存在。 整个时间对用户是不可见的。 这个元素有ID brim-treadmill

在加载页面或改变方向之后,Brim使用Scream来检测页面是否在minimal-ui视图中(之前在minimal-ui中的页面,并且如果内容高度是已重载的页面将保留在minimal-ui中大于视口高度)。

当页面处于minimal-ui中时,Brim将禁用文档的滚动(以一种不影响主元素内容的安全方式进行)。 禁用文档滚动可以防止在向上滚动时意外地离开minimal-ui。 根据最初的iOS 7.1规范,点击顶部栏会将其余部分恢复。

最终结果如下所示:

在iOS模拟器边缘。

为了文档的缘故,如果您更愿意编写自己的实现,值得注意的是,在orientationchange事件之后,您不能使用Scream来检测设备是否处于最简单的状态,因为window尺寸不能反映新的方向,直到旋转animation已结束。 您必须将侦听器附加到orientationchangeend事件。

尖叫和orientationchangendnd已被开发作为这个项目的一部分。

由于没有编程方式来模仿minimal-ui ,所以我们想出了一个不同的解决方法,使用calc()和已知的iOS地址栏高度来达到我们的优势:

下面的演示页面( 也包括更多的技术细节 )将提示用户滚动,然后触发一个软全屏(隐藏地址栏/菜单),其中标题和内容填充新的视口。

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

只要告别minimal-ui(现在)

诚然, minimal-ui既有用又有害,我想现在有一个平衡,有利于更新,更大的iPhone。

我一直在处理与我的js框架的HTML5应用程序的问题。 经过多次试图解决之后,每一个都有自己的缺点,我投降了考虑iPhone之前的6个空间丢失。鉴于这种情况,我认为唯一可靠和可预测的行为是一个预先确定的行为。

总之,我最终阻止了任何forms的minimal-ui ,所以至less我的屏幕高度总是相同的,你总是知道你的应用程序的实际空间。

随着时间的推移,足够的用户将有更多的空间。


编辑

我怎么做

这是一个简单的,为了演示的目的,但应该为你工作。 假设你有一个主容器

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

然后:

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

  2. 当到达滚动的边界时,我阻止过度滚动。 这一个是在我的代码更深,但我认为你可以遵循这个答案的基本function的原则。 我认为它可以稍微闪烁,但会做这项工作。


看演示 (在iPhone上)

作为一个旁注:这个应用程序也是可collections的,因为它使用内部路由到哈希地址,但我也添加了提示iOS用户添加到家里。 我觉得这种方式有助于忠诚和回访者(所以失去的空间又回来了)。

我发现解决这个问题的最简单方法是将用户代理是iphone的任何请求的body和html元素的高度设置为100.1%。 这只适用于景观模式,但这就是我所需要的。

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

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

这里的根本问题似乎是,如果内容等于或小于视口,向下滚动时,iOS8 safari不会隐藏地址栏。

正如你已经发现,在底部添加一些填充可以解决这个问题:

 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 eg an input if ( !document.activeElement || document.activeElement === document.body ) { document.body.scrollIntoViewIfNeeded(true); } }); 

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

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

a)您可以使用屏幕底部带有动作button的抽屉; 如果文档滚动并且底部条消失,则点击位于屏幕底部的button将首先出现底部条,然后可点击。 而且,这个东西的工作方式,导致在底部有button的模态的麻烦。

b)当使用overflown元素时,在主要css更改的情况下唯一重新绘制的东西是可视屏幕中的元素。 这使我在使用JavaScript改变运行多个元素的CSS时有了巨大的性能提升。 例如,如果您有20个元素的列表需要重绘,并且只有两个元素在屏幕上的溢出元素中,则只有那些被重新绘制,而其他元素在滚动时重新绘制。 没有它,所有20个元素都重新粉刷。

..当然这取决于项目,如果你需要我提到的任何function。 Google使用overflown元素让gmail使用我在a)中描述的function。 伊莫,这是值得的,即使考虑到旧的iPhone手机的小高度(372像你说的)。

我从@doublesharp中遇到了这个解决scheme,它对我来说非常出色,所以我想我会在这里分享它:

 // track width, set to window width var width = $(window).width(); // fire on window resize $(window).resize(function() { // do nothing if the width is the same if ($(window).width()==width) return; // ... your code }); 

因此,对于像iOS 8地址栏这样的东西,当您向下滚动时,地址栏大小调整将不会触发$(window).resize()代码。

我还没有完成iOS的网页devise,但是从我记得在WWDC会话和文档中看到的,Mobile Safari中的search栏和操作系统上的导航栏现在将自动resize缩小,以显示更多内容。

您可以在iPhone上的Safari中testing,并注意,当您向下滚动以查看页面上的更多内容时,导航/search栏会自动隐藏。

也许离开地址栏/导航栏,而不是创build一个全屏体验是最好的。 苹果公司很快就没有这样做了。 最多他们不会自动控制地址栏显示/隐藏。

当然,你正在失去屏幕的房地产,特别是在iPhone 4或4S,但似乎没有替代的Beta 4。