IOS6+ 下,使用position:sticky实现粘性布局

回顾一下

开通博客之后,潦草的写了几篇,之后由于没时间,加上文笔不好等等(好吧,都是借口),基本上就没怎么写过了,其实平时也做了一些记录,但就是犯懒,没有去整理。现在打算重新开始了,记录一些自己学习过程中,对一些新的知识的理解,不一定对,目的就是鞭策自己不断的去反省,总结。


正文

场景

OK,回归正题。相信大家在移动端页面里,经常会遇到一个场景,页面里有个导航栏,当用户向下滑动的时候,将导航栏固定到页面顶部。

这种布局其实实现起来非常简单,通常我们都会监听window的scoll事件,当页面滚动到某个位置时,将导航条的position设为fixed,否则,取消fixed。

问题来了

但是~~在安卓设备里,没毛病,在iOS设备里,问题就来了,在iOS上会发现,页面向下滑,手指离开页面,还会有一段滚动,但是滚到相应的位置时,我们的导航条并没有fix到顶部,而是当页面停止滚动的时候,fixed才会生效。所以这时候,导航栏会有个跳动的效果,刚开始测试妹子给我提bug,我一度认为这尼玛不是bug啊。。。后来研究了一下

原因及解决方案

在iOS设备上,iOS下的浏览器会在页面滚动的时候,会暂停所有js的执行,直到滚动停止才会继续去执行js(注意暂停了所有js的执行,所以考虑用setTimeout或setInterval也是没有用的)。所以页面滚动时,scroll事件在iOS的浏览器下并不会持续被触发,而是在页面滚动停止后,才会去触发一次scroll事件。 这就是问题的根源。

然后,万能的CSS,position还有一个不常见的属性:sticky,使用position:sticky,可以完美的解决这个问题,但这个属性支持度并不好,因此可以先通过以下代码先判断是否支持:

  1. _supportSticky() {
  2. let e, i = “-webkit-sticky”, s = document.createElement(“i”);
  3. s.style.position = i;
  4. e = s.style.position;
  5. s = null;
  6. return e === i
  7. }

如果支持,就给设置position: -webkit-sticky,top:0;这样,就可以完美实现fixed效果,但是注意:如父容器设置属性overflow:hidden,父容器根本就不能滚动,所以sticky元素也不会有滚动然后固定的情况。sticky效果就不会生效。

这样,我们在iOS平台里,先判断是否支持sticky属性是否支持,如果支持,就使用sticky,完美~