我正在为移动手机构建单页面Web应用程序。该应用程序应该实现“屏幕”之间的过渡(就像其他任何移动应用程序,例如Facebook,Twitter),并且这些过渡应该是动画效果(从左到右滑动)。每个屏幕在过渡期间都必须保留其滚动位置。
一个显而易见的解决方案是:
Viewport
+----------+
|+--------+| +--------+ +--------+ +--------+
|| DIV1 || | DIV2 | | DIV3 | | DIV4 |
|| || | | | | | |
|| || | | | | | |
|| || | | | | | |
|| || | | | | | |
|+--------+| +--------+ +--------+ +--------+
+----------+
不同的屏幕被放入容器中(DIV1、DIV2等),这些容器被设计成适合屏幕大小的 (position: absolute; width: 100%; height: 100%; top: 0
),并且具有 overflow-x: scroll
属性。容器被相邻地定位,过渡的方式就像动画化它们的 left
属性一样简单。
到目前为止还好。
问题在于:在这种实现中,当用户向下滚动时,移动浏览器中的地址栏不会消失。
我说的是这个功能:
这是因为移动浏览器仅在用户滚动 body
时才会这样做,而不是在 body
中的容器中滚动。有一些解决方案(several)(suggestions),但不适用于所有目标平台(Android Chrome 和原生浏览器,iPhone Safari),而且非常 hacky。我想保留浏览器的原始行为。
因此 - 显然 - 需要将滚动留在 body 上。这意味着容器必须是“全长”的(而不是溢出滚动),仍然相邻地定位。这就是过渡变得困难的地方。
当从 DIV1 过渡到 DIV2 时,我的当前解决方案包括以下步骤:
- 将 DIV2 的
top
定位到窗口当前的scrollTop
- 动画化 DIV1 和 DIV2 的
left
属性,以便 DIV2 填充屏幕 - 一旦动画完成,将 DIV2 的
top
移动到0
,以便用户无法向上滚动超过此屏幕的顶部 - 将窗口的 scrollTop 移动到 0
- 隐藏 DIV1(以防它比 DIV2 更长)
反向过渡回 DIV1 类似。实际上,这非常好用(尽管非常复杂,并且使用了转换事件监听器),但不幸的是,在 iOS Safari 下,在步骤 3 和 4 之间存在一个非常丑陋的闪烁效果,因为它会在步骤 3 完成后立即呈现页面,而不等待步骤 4。
我正在寻找一个与框架无关的 (vanilla JS) 解决方案。
jQuery === javascript
并在 JavaScript 问题中发布 jQuery 答案的情况。jQuery 是一个在 web 平台过渡期证明有用的库,但越来越不相关了。放手吧! - gphilip