使用PushState开发单页面应用,在iOS端如果点击后退或向左滑屏,一定几率可能会导致白屏。
重现步骤
- 做A、B两个页面,A很长,足以向下滚动好几屏;B很短,没的滚动。
- 页面A的显示需要一个短暂的Loading,先显示一个Loading中的短页面,一会后再显示A的完整长页面
- 页面A底部包含一个进入页面B的按钮(通过PushState跳转),例如使用
React-Router
- 进入页面A,滚到底部,点击按钮,跳至页面B
- 在页面B,从屏幕边缘左滑或点击后退按钮,返回上一页
- 白屏
问题原因
- iOS的BUG,后退时如果更新页面内容两次,会导致第二次更新失效
解决
有两种解决方案
方案一
- 后退后,在第二次更新页面后,调用window.scrollTo(0, -0.1);
方案二
- 把A的Loading页面做的足够长(高度大于等于A的完整内容高度)即可
- 此方案甚至可以实现返回后自动滚到上一次的位置
方案三
- 从B返回之前,只要在B向下滚动至少1像素,就没有这个问题
我最终选择的解决方案
仅对iOS做特殊处理:
- 统一View内部的Loading样式,height:9999
<!-- 外面用height: 9999 -->
<div className='wrapper loading' style={{height: 9999}}>
<div style={{position: 'fixed'}}>
<!-- 里面的用fixed 保证loading始终可见 -->
</div>
</div>
(正文完)