fixed在微信下的BUG

最近在一个项目中,碰到了一个问题,是属于微信内部的问题,或者说,是属于APP内部的问题,它的根源来自于fixed定位以及-webkit-overflow-scrolling的组合使用,虽然现在还无法理解问题的根源,但这里可以简单的说一下,问题的情况,以及解决方案。

1:状况描述

解决方案说的再清楚,都不及一个示例来看,看到的明显,所以这里,我们就直接来看示例吧:

如果您在PC端,可以使用微信扫码:

也可以直接去查看,直接扫码:

也可以直接去查看源码:出现问题的DEMO;http://www.zhangyunling.com/study/2016/20161204/index-1.html

在微信中看看,然后在浏览器中在看看哦,是否发现哪里有差距呢?

2:反向排查

是什么问题导致这种情况的出现呢?

看看我们的代码,结构异常简单,比如,其HTML代码(关键代码),就是如下的样式:


固定定位的元素

固定定位在IOS的微信APP内部的问题

该问题,在一些其他的APP内部,也会出现

控制中间区域的部分

到底了

而CSS代码,也是很简单的使用:


.fixed{
    position:fixed;
    top:40%;
    left:0px;
    width:2em;
    background-color:#000;
    color:#fff;
    padding:5px;
    line-height:1.5em;
}
.wrapper{
    position:absolute;
    top:0px;
    left:0px;
    right:0px;
    bottom:0px;
    overflow:auto;
    -webkit-overflow-scrolling : touch;
    padding:10px;
}


都是很常见的代码,而且基本可以保证,在移动端,没有什么兼容性问题,那么前面的问题,又是哪里来的呢?

如果说,这个真的是有兼容性导致的,那么这里,唯一有兼容性问题的一个东西,也只剩下:-webkit-overflow-scrolling了。它用来在IOS系统下,处理滑动惯性的。

既然发现了问题,那么就去尝试解决一下,既然是这个属性的问题,那么就再来换一个DEMO,然后所有的代码不变,只去掉这一个属性试试呗。

也可以直接去查看:

也可以直接去查看源码:去掉-webkit-overflow-scrolling的DEMO

去掉了这个属性之后,确实好了,前面的问题也不在出现了,如果只是在Android的手机上,那么这样做,完全没有问题,但是在IOS下,就变得体验非常不好了,感觉就像是卡顿的样子,再也没有之前滚动的流畅性了,这样的体验,还不被批的体无完肤,完全没法交工的么。

那么只能继续看其他的影响了。

3:继续排查

抛开特殊属性的问题,那么这里只剩下两个基本的属性了,对于固定定位来说,.fixed的样式,已经是属于最简的了,无法再做更多的简化了,那么只能从.wrapper元素来看了。

这里的wrapper的元素,也算很简单的,但是唯一的疑惑就是,为何这里要使用绝对定位呢?

如果我不使绝对定位,而是直接使用普通流呢?

那么,就去除掉这个绝对定位试试:

直接扫二维码查看DEMO:

也可以直接去查看源码:去掉absolute的DEMO

果然OK了,原来是绝对定位的影响啊,去掉之后,果然变得很流畅了,而且也fixed元素,位置固定,表现正常了。

那么问题就这样解决了吗?当然没有。

4:为什么之前使用绝对定位

回想一下,最前面的代码,为什么这里要使用绝对定位呢?如果没有其他的限制,使用普通文档流布局,不是最佳的选择吗?

但是在最初的示例中,却使用一个绝对定位呢?

其实,因为在真正的项目中,需求并不是这么简单的,在这个页面上,顶部其实是要固定一个输入框的,而顶部固定输入框的情况,如果直接使用普通流布局的话,就会有兼容性问题,这个问题就不止是在微信内部了,算是在整个IOS系统的浏览器下,都会出现这个问题,那这更不可取了,为了解决一个在某些APP中出现的问题,导致在IOS系统下的所有的浏览器,都会出现另外的问题。

关于输入框的问题,可以查看之前的一篇文章:IOS输入框固定

所以,这里我们还必须使用绝对定位来做这个处理。

那么,这个问题又要如何解决呢?

通过CSS的解决方案,是无法解决这个问题了,而这个问题的出现,又跟JS毫无关系,并且,在前面的文章中,也说过一个问题,就代表了,我们根本不可能通过JS,来解决IOS系统下的这个问题。

因为在IOS的系统滚动时,是不会进行渲染的,这也是这里问题的原因。

为什么无法通过JS来解决这个问题,可以参考之前的一篇文章:

不能通过CSSJS来解决,那么现在只能去考虑一下HTML的代码了,是不是HTML的代码,布局出现了问题,所以才导致了该问题的出现呢?

5:看看HTML的布局

看一下关键的两个元素的布局:


固定定位的元素

如果这里再变动,那就只能说,把这两个元素由父子关系,变为兄弟关系了。

所以,接下来就这么试一试吧。

直接扫二维码查看DEMO:

也可以直接去查看源码:改结构为兄弟关系的DEMO

哇…竟然很完美的解决了

6:这是为什么呢?

太官方的解释,我并没有找到,但是这里的问题的来源,从前面的示例中,可以有一些简单的总结。

首先,IOS想要页面的滚动变得流畅,所以才有的这个元素:-webkit-overflow-scrolling,那么这个属性的存在,就可能会引起一些其他的问题,这个解释不了更多了…

还有,语义化标签是个很重要的概念,这里也更进一步的说明了这个问题,其实,在最初之所以把fixed元素,放在其他的元素内部,主要是为了之后的操作更方便,当然在没有使用-webkit-overflow-scrolling的属性的时候,也确实没有问题,但是这个两个属性,碰到了一起,就出现问题了。

IOS系统下,fixed的属性的诸多问题,这里又添加了一员,希望大家多多注意,平时对于fixed的使用,也多多注意,比如把所有的fixed元素,都放在body元素的下面,而不是放在其他子元素的内部。

这样也可以避免一些不必要的麻烦。

对于为什么出现这个问题,没有更深入的认识,所以这里只能把问题的根源稍微说一下,如果您有更深的认识,请指教啦。

总结

本篇文章的内容,本篇的大部分都是属于,以测试实例来反推原因,并没有找到官方的说明来解释这个问题,并且这个只在IOS系统的一些APP内部才会出现问题,而在IOS自带的Safari浏览器,并没有这个问题的出现,所以这个也许是一些APP的内部,对于浏览器有一些修改吧。

如果您对这个情况,有更深层次的理解,恳请指教,谢谢。

本篇到此为止。

如果您发现文中有描述错误或者不当的地方,请留言指出,不胜感激,谢谢!

本文属于原创文章,如需转载,请注明出处,谢谢!

本文地址:http://www.zhangyunling.com/?p=684

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

fixed在微信下的BUG》有2个想法

  1. vito说道:

    是这么个问题,666

  2. 总结的不错。谢谢