(这是一个多部分的问题,我会尽力总结场景。)
我们目前正在构建一个响应式网络应用程序(新闻阅读器),它允许用户在选项卡式内容之间滑动,以及在每个选项卡式内容内垂直滚动。
解决此问题的常用方法是使用填充浏览器视口的包装器 div
,将 overflow
设置为 hidden
或 auto
,然后在其中水平和/或垂直滚动。
这种方法很棒,但有一个主要缺点:由于文档的高度与浏览器视口完全相同,因此移动浏览器不会隐藏地址栏/导航菜单。
有 numerous hacks and viewport properties 可以让我们获得更多的屏幕空间,但没有一个比 minimal-ui
更有效(在 iOS 7.1 中引入)。
昨天有消息称 iOS 8 beta4 已从 Mobile Safari 中删除了 minimal-ui
(请参阅 iOS 8 Release Notes 中的 Webkit 部分),这让我们感到疑惑:
Q1。是否仍然可以隐藏 Mobile Safari 上的地址栏?
据我们所知,iOS 7 no longer responds 到 window.scrollTo
hack,这表明我们必须忍受较小的屏幕空间,除非我们采用垂直布局或使用 mobile-web-app-capable
。
Q2。是否还能有类似的软全屏体验?
soft fullscreen 我的意思是不使用 mobile-web-app-capable
元标记。
我们的网络应用程序可访问,任何页面都可以使用本机浏览器菜单添加书签或共享。通过添加 mobile-web-app-capable
,我们可以防止用户调用此类菜单(当它保存到主屏幕时),这会使用户感到困惑和反感。
minimal-ui
曾经是中间立场,默认情况下会隐藏菜单,但 keeping it accessible with a tap - 尽管 Apple 可能由于其他可访问性问题(例如用户不知道在哪里点击以激活菜单)而将其删除。
Q3。全屏体验值得麻烦吗?
似乎 fullscreen API 不会很快出现在 iOS 上,但即使是这样,我也看不出菜单将如何保持可访问性(Android 上的 Chrome 也是如此)。
在这种情况下,也许我们应该让移动 safari 保持原样,并考虑视口高度(对于 iPhone 5+,它是 460 = 568 - 108,其中 108 包括操作系统栏、地址栏和导航菜单;对于 iPhone 4 或旧的,它是 372)。
希望听到一些替代方案(除了构建本机应用程序)。
在 iOS 8 中,minimal-ui 视口属性是 no longer supported。但是,minimal-ui 本身并没有消失。用户可以通过“触摸向下”手势进入最小用户界面。
管理视图状态有几个前提条件和障碍,例如,要让最小用户界面工作,必须有足够的内容让用户能够滚动;为了使最小用户界面持续存在,窗口滚动必须在页面加载时和方向更改后偏移。但是,there is no way of calculating the dimensions of the minimal-ui 使用了 screen
变量,因此无法提前告知用户何时处于最小用户界面中。
这些观察结果是作为开发 Brim – view manager for iOS 8 的一部分进行研究的结果。最终实现的工作方式如下:
加载页面时,Brim 将创建一个跑步机元素。跑步机元素用于为用户提供滚动空间。跑步机元素的存在确保用户可以进入最小用户界面视图,并且如果用户重新加载页面或更改设备方向,它会继续存在。它对用户始终是不可见的。此元素具有 ID 边缘跑步机。在加载页面或更改方向后,Brim 正在使用 Scream 检测页面是否处于最小 ui 视图中(如果内容高度为大于视口高度)。当页面处于最小用户界面时,Brim 将禁用文档的滚动(它以一种不影响主元素内容的安全方式执行此操作)。禁用文档滚动可防止向上滚动时意外离开最小用户界面。根据最初的 iOS 7.1 规范,点击顶部栏会带回 chrome 的其余部分。
最终结果如下所示:
https://i.stack.imgur.com/mVciy.gif
为了记录,如果您更喜欢编写自己的实现,值得注意的是,您不能在 orientationchange 事件之后立即使用 Scream 来检测设备是否处于最小 UI,因为 window
维度确实在旋转动画结束之前不反映新方向。您必须将侦听器附加到 orientationchangeend 事件。
Scream 和 orientationchangeend 已作为该项目的一部分进行开发。
由于没有模仿 minimal-ui
的编程方式,我们提出了一种不同的解决方法,使用 calc()
和已知的 iOS 地址栏高度来发挥我们的优势:
以下演示页面 (also available on gist, more technical details there) 将提示用户滚动,然后触发软全屏(隐藏地址栏/菜单),其中标题和内容填充新视口。
<!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。
在使用我的 HTML5 应用程序的 js 框架时,我一直在处理这个问题。在尝试了许多解决方案后,每一个都有其缺点,我放弃了考虑在 6 之前的 iPhone 上丢失的空间。鉴于这种情况,我认为唯一可靠且可预测的行为是预先确定的。
简而言之,我最终阻止了任何形式的最小用户界面,所以至少我的屏幕高度总是相同的,你总是知道你的应用程序有多少实际空间。
在时间的帮助下,足够多的用户将拥有更多空间。
编辑
我是怎么做的
出于演示目的,这有点简化,但应该适合您。假设你有一个主容器
html, body, #main {
height: 100%;
width: 100%;
overflow: hidden;
}
.view {
width: 100%;
height: 100%;
overflow: scroll;
}
然后:
然后使用 js,我将#main 的高度设置为窗口的可用高度。这也有助于处理 iOS 和 Android 中发现的其他滚动错误。这也意味着您需要处理如何更新它,请注意;到达滚动边界时,我会阻止过度滚动。这个在我的代码中有点深,但我认为你也可以遵循这个答案的原则来获得基本功能。我认为它可能会闪烁一点,但会完成这项工作。
查看演示(在 iPhone 上)
作为旁注:这个应用程序也是可收藏的,因为它使用内部路由到散列地址,但我还添加了一个提示 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 e.g. an input
if (
!document.activeElement
|| document.activeElement === document.body
) {
document.body.scrollIntoViewIfNeeded(true);
}
});
上面的 css 应该有条件地应用,例如 UA 嗅探将 gt-ios8
类添加到 <html>
。
scrollIntoViewIfNeeded
,它是 scrollIntoView
(developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView) 的非标准派生。顾名思义,该方法将元素滚动到视图中。 true
参数表示将视图与元素的顶部对齐。这实际上应该阻止您滚动。但实施存在缺陷。
我想评论/部分回答/分享我的想法。我正在为即将到来的一个大型项目使用溢出-y:滚动技术。使用它有两个主要优点。
a) 您可以从屏幕底部使用带有操作按钮的抽屉;如果文档滚动并且底部栏消失,点击位于屏幕底部的按钮将首先使底部栏出现,然后可以点击。此外,这个东西的工作方式会导致在最底部有按钮的模式出现问题。
b) 当使用溢出的元素时,在发生重大 css 更改的情况下,唯一需要重新绘制的内容是可视屏幕中的内容。当使用 javascript 动态更改多个元素的 css 时,这给了我巨大的性能提升。例如,如果您有一个需要重绘的 20 个元素的列表,并且其中只有两个在溢出元素的屏幕上,则只有那些被重绘,而其余的在滚动时被重绘。没有它,所有 20 个元素都将被重新绘制。
..当然,这取决于项目以及您是否需要我提到的任何功能。 Google 使用溢出的 gmail 元素来使用我在 a) 中描述的功能。 Imo,即使考虑到旧款 iphone 的小高度(如您所说的 372 像素),这也是值得的。
这是可能的,使用我在 (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
可以让 Web 应用程序在 iOS 和 Android 中全屏运行,it is called a PWA 经过大量努力,这是解决此问题的唯一方法。
PWA 为开发提供了许多不容错过的有趣选项。我已经做了一对,看看这个Public and Private Tender Manual For Designers(西班牙语)。 And here is an English explanation from the CosmicJS site
我还没有为 iOS 做过网页设计,但从我记得在 WWDC 会议和文档中看到的内容来看,Mobile Safari 中的搜索栏和整个操作系统的导航栏现在会自动调整大小和缩小以显示更多内容。
您可以在 iPhone 上的 Safari 中对此进行测试,并注意到,当您向下滚动以查看页面上的更多内容时,导航/搜索栏会自动隐藏。
最好保留地址栏/导航栏,而不是创建全屏体验。我认为苹果不会很快这样做。而且他们最多不会自动控制地址栏何时显示/隐藏。
当然,您正在失去屏幕空间,特别是在 iPhone 4 或 4S 上,但从 Beta 4 开始似乎没有替代品。
I haven't done web design for iOS
- 如果您正在做网页设计,您可以为每个平台做这件事。因为网络在每个平台上。