在我们使用iOS Safari的浏览器时,会发现一个很酷炫但是对开发者造成很大困扰的功能 -- 上划页面的时候工具栏和地址栏会隐藏起来。
当页面向上滑动的时候,工具栏会隐藏,此时的window.innerHeight会发生变化,但是css中的vh是不会变的,100vh = 隐藏工具栏时的window.innerHeight。(在IphoneXR中,显示工具栏的时候window.innerHeight = 719px,工具栏隐藏时候window.innerHeight = 833px)
如果你的页面的本来设计就是可以滑动的长页面是没有什么影响的,但是如果你的页面准备做成只有一个视口大小的单页面应用,那就会出现问题。
因为就算你设置width: 100%,页面还是会出现滚动,并且向上滚动达到一定阈值的时候,工具栏会隐藏,布局完全混乱。并且且在横屏和竖屏下,工具栏的高度也是不同的。
此外如果我们为元素设置absolute或fixed属性,想要将它们固定在底部位置的话,Safari也不能如我们所愿。如上文所讲,实际上你的页面有一部分被底部的工具栏挡住了,所以我们设置在底部位置的元素也会被工具栏挡住。
那么如何解决这个问题呢,以一个视口大小的单页面应用为例。
...
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0,maximum-scale=1.0,viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="browsermode" content="application">
<meta name="full-screen" content="yes" />
<meta name="x5-fullscreen" content="true" />
<meta name="x5-page-mode" content="app" />
<meta name="360-fullscreen" content="true" />
</head>
<html>
<body>
<div id="app">
...
<div id="bottom"></div>
</div>
</body>
</html>
...
注意这些meta头是我们移动端开发时的必备hardcode,必须要掌握其含义。
首先我们要做的工作是禁止上划的时候隐藏工具栏。虽然工具栏很丑并且和我们的界面并不搭,我们想把他隐藏掉,但是苹果爸爸设定的默认行为是显示工具栏,我们就乖乖听爸爸的话好了。
html, body {
overflow: hidden;
}
是的,隐藏工具栏既然是页面向上滚动的时候会发生的现象,那么我们禁止页面的滚动不就好了,反正我们单一视口大小的应用也不需要滚动页面。
接下来我们想要将底部的id=bottom的组件固定在页面最底下。因为不同型号的iPhone中的Safari的底部工具栏高度也是不同的,但是window.innerHeight却永远等于当前视口的高度,所以我们需要借助这个属性来使元素固定在页面的底部。
const height = window.innerHeight;
document.getElementById('bottom').style.height = '120px';
document.getElementById('bottom').style.top = height - 120 + 'px';
// or
document.getElementById('bottom').style.height = '1rem';
document.getElementById('bottom').style.top = `calc(${height}px - 1rem)`;
如此,我们就完成了一个移动浏览器中固定在视口底部的元素。
接下来开始技术总结:
- 移动端要避免使用100vh 来创造一个全屏元素,可以使用window.innerHeight来获取实际的浏览器内容部分高度。
- iOS Safari中可以设置根元素为高度超过视口的元素并让其禁止滚动来避免上划屏幕时工具栏收起。
- 在移动端开发中,HTML文件的meta头的设置很重要,我们可以通过viewport-fit来调整在iOS刘海屏下的页面所占大小。
iOS Safari单一视口应用的技术总结完毕。