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

(这是一个多部分的问题,我会尽我最大的努力来总结这个场景。)

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

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

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

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

昨天有消息称,iOS 8 beta4已经从移动Safari中删除了minimal-ui(参见iOS 8发布说明中的Webkit部分),这让我们想知道:

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

据我们所知,iOS 7 不再有回应window.scrollTo黑客,这表明我们必须接受更小的屏幕空间,除非我们采用垂直布局或使用mobile-web-app-capable

Q2。还有可能拥有类似的软全屏体验吗?

这里的软全屏指的是不使用mobile-web-app-capable元标记。

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

minimal-ui曾经是中间地带,默认情况下隐藏菜单,但用水龙头打开 -尽管苹果可能由于其他可访问性问题(例如用户不知道点击哪里来激活菜单)而删除了它。

第三季。全屏体验值得费心吗?

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

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

很乐意听到一些替代方案(除了构建原生应用程序)。

166627 次浏览

我没有为iOS做过网页设计,但根据我在WWDC会议和文档中看到的,移动Safari中的搜索栏和操作系统中的导航栏现在会自动调整大小和缩小,以显示更多的内容。

您可以在iPhone上的Safari中测试这个功能,并注意到,当您向下滚动以查看页面上的更多内容时,导航/搜索栏会自动隐藏。

也许保持地址栏/导航栏不变,不创造全屏体验才是最好的。我认为苹果短期内不会这么做。他们最多不会自动控制地址栏何时显示/隐藏。

当然,你正在失去屏幕空间,特别是在iPhone 4或4S上,但在Beta 4之前似乎没有替代方案。

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

a)你可以使用屏幕底部带有操作按钮的抽屉;如果文档滚动,底部栏消失,点击位于屏幕底部的按钮将首先使底部栏出现,然后是可点击的。此外,这个东西的工作方式,导致麻烦的情态动词有按钮在最底部。

b)当使用一个溢出的元素时,在css发生重大变化的情况下,唯一需要重新绘制的是可视屏幕中的元素。这给了我一个巨大的性能提升时,使用javascript修改css的多个元素的飞行。例如,如果你有一个20个元素的列表,你需要重新绘制,其中只有两个在屏幕上的溢出元素中,只有那些被重新绘制,而其余的在滚动时被重新绘制。如果没有它,所有20个元素将被重新绘制。

..当然,这取决于项目,以及你是否需要我提到的任何功能。谷歌使用gmail的溢出元素来使用我在a)中描述的功能。在我看来,这是值得的,即使考虑到旧iphone的小高度(如你所说的372px)。

由于没有编程方法来模拟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>

这里的根本问题似乎是,当向下滚动内容等于或小于视口时,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 e.g. an input
if (
!document.activeElement
|| document.activeElement === document.body
) {
document.body.scrollIntoViewIfNeeded(true);
}
});

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

暂时和最小ui说再见吧

的确,minimal-ui可能既有用又有害,我想现在的权衡有了另一个平衡,有利于更新、更大的iphone。

我一直在处理这个问题,同时与我的js框架为HTML5应用程序工作。在尝试了许多解决方案后(每个方案都有其缺点),我不得不考虑iphone 6之前的手机会丢失空间。 在这种情况下,我认为唯一可靠且可预测的行为是预先确定的行为

简而言之,我结束了防止任何形式的minimo -ui,所以至少我的屏幕高度总是相同的,你总是知道你的应用程序的实际空间。

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


编辑

我怎么做

出于演示目的,这有点简化,但应该适用于您。假设你有一个主容器

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

然后:

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

  2. 当达到滚动的边界时,我阻止过度滚动。这个在我的代码中有点深,但我认为你也可以遵循这个答案的基本功能原则。我认为它可能会有点flickr,但会做的工作。


查看演示(在iPhone上)

作为旁注:这个应用程序也是可书签的,因为它使用内部路由到散列地址,但我还添加了一个提示iOS用户添加到home。我觉得这种方式有助于提高忠诚度和回头客(因此失去的空间又回来了)。

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

管理视图状态有几个前提条件和障碍,例如,为了让最小化ui工作,必须有足够的内容让用户滚动;为了保持最小化ui,窗口滚动必须在页面加载和方向改变后偏移。然而,没有办法计算最小ui的维数使用screen变量,因此无法提前告诉用户何时处于最小ui。

这些观察结果是作为开发Brim - view manager for iOS 8 . bb0的一部分的研究结果。最终实现的工作方式如下:

当页面加载时,Brim将创建一个跑步机元素。 跑步机元素是用来给用户空间滚动。的存在 跑步机元素确保用户可以进入最小用户界面视图 并且,如果用户重新加载页面或更改,它将继续存在 设备定位。它对用户始终是不可见的。这 元素ID为brim-treadmill

加载页面或改变方向后,Brim正在使用 尖叫来检测页面是否在 最小用户界面视图(之前已经在最小用户界面中的页面 如果内容高度为,则被重新加载将保持在最小界面 大于视口高度) 当页面在最小界面时,Brim将禁用滚动 文档(它在安全 Way 不影响 主元素的内容)。禁用文档滚动 防止在向上滚动时意外地离开最小ui。 根据最初的iOS 7.1规范,点击顶部栏会返回

最终结果是这样的:

Brim in iOS simulator.

为了文档的方便,如果你更喜欢写自己的实现,值得注意的是,你不能在orientationchange事件之后直接使用尖叫来检测设备是否在minimal-ui中,因为window维度在旋转动画结束之前不会反映新的方向。你必须给orientationchangeend事件附加一个监听器。

尖叫orientationchangeend是这个项目的一部分。

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

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

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

这是可能的,使用类似下面的例子,我在(https://gist.github.com/bitinn/1700068a276fb29740a7)工作的帮助下组合在一起,在iOS 11上不太管用:

以下是在iOS 11.03上运行的修改后的代码,如果它对你有效,请评论。

关键是为BODY添加一些大小,以便浏览器可以滚动,例如:高度: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 < / p >

我们可以让web应用在iOS和Android上全屏运行,经过艰苦的工作,这是解决这个问题的唯一方法。

PWAs为发展提供了许多有趣的选择,不容错过。我已经做了一些,看看这个设计人员公开和私人投标手册(西班牙语)。这里有一个来自CosmicJS网站的英文解释