记IOS Safari下的小知(问)识(题)

近期做了一些移动端的事儿,本来顺顺利利的提了测,感觉没什么问题,不过测试同学一会反映一个ios safari的问题过来(留下了贫穷的泪水),在这里记录一下,大家遇到的时候也可有应对措施。

1、vh单位问题

在我们的代码中,可能会用到vh来作为宽度单位,如果用到了,可能你这就要小心。

比如我们想实现下图这样的场景:


image.png

最简单的思路其实就是一个flex布局,然后头部和底部一定宽度,内容区flex:1即可,但是,如果你给body使用了100vh来定义范围,那么,你将在IOS下看到:


image.png

问题来了,我的footer跑哪里去了,仔细看看,你会在safari底部的操作区中看到一点点浅蓝,像是被操作区挡住了的东西,那就是你的footer

原因:这并不是一个bug,而是webkit为了保障IOS 60FPS的方案(算是一个功能吧),具体见 https://bugs.webkit.org/show_bug.cgi?id=141832

解决对策:

1、放弃100vh吧,用100%。

2、放弃100vh吧,使用 -webkit-fill-available [该值作用是尽可能的撑满可用空间]

如下:

html {

  height:-webkit-fill-available;

}

body {
  height: 100vh;
  height: -webkit-fill-available;
}

2、meta viewport失效的问题

在移动端,我们可能会写这样的标签

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1,

用于确定视窗大小,同时禁止用户手动放大缩小,但是,从IOS 10开始,他就不在支持利用user-scalable禁止用户双指放大,缩小。

原因:相关说明见https://webkit.org/blog/7367/new-interaction-behaviors-in-ios-10/,我截取了重要的部分见下图。

image.png

简而言之就是,决定内容文本的大小,是用户已有的权利,我们不应该组织,我们应该自己意识到这点,并且在放大缩小的时候能保证页面内容正常。

解决对策: 取消多指事件 **gesturestart**默认行为,该事件为IOS独有,详见https://developer.mozilla.org/en-US/docs/Web/API/Element/gesturestart_event

document.addEventListener('gesturestart', function (event) { 
  event.preventDefault(); 
});

3、safari滚动阻尼问题

在safari下,为了让用户滚动更流畅,我们经常可以过量滚动,然后触发一定的回弹效果。像这个视频一样


阻尼.gif

看起来很舒服,很符合用户操作对不对,可是一但出现额外的滚动区域的话,就会产生奇怪的问题,比如你想滚动一个iframe的滚动条,然后发现滚动到body下的滚动,触发了回弹效果。

解决对策:

1、取消掉body的滚动,仅在支持滚动区域的地方加入滚动效果

html, body {
    height: 100%;
    overflow: hidden;
}

.scroll-wrap{
  overflow:auto
}

**该方法缺陷是好处不会全局产生回弹阻尼效果了,但是对应的滚动元素体依然会这样**

**2、使用iNoBounce库[https://github.com/lazd/iNoBounce](https://github.com/lazd/iNoBounce),然后在对应想取消掉回弹的元素上增加 overflow, height, -webkit-overflow-scrolling属性即可**
```html
.scroll-wrap{
  overflow:auto;
  -webkit-overflow-scrolling: touch;
  height:100px;
}

其原理也比较简单,主要是对touchstart和touchmove事件进行监听,然后随时计算滚动条位置,如果到底了,取消掉事件的默认行为。

推荐阅读更多精彩内容