转载请注明英文原文和翻译出处原文地址:Issueswithpositionfixed&scrollingoniOS原作者:RemySharp翻译地址:移动端固定andscroll问题翻译作者:镀金大师霍麒麟最近在iOS端做H5页面时遇到一个定位问题:1.页面滚动时position:fixed元素的属性值变为absolute,又返回fixed当页面停止滚动时;2、当滚动容器元素中存在fixed定位的元素时,拖动容器元素会出现闪烁问题。在寻求解决方案的过程中,看到这篇文章,很好的解释了这个问题的原因,所以翻译出来供大家参考。在翻译的过程中,对原文的字幕进行了修改,方便大家阅读。如果翻译有误,也可以在评论中指出,谢谢。以下为译文:随着iOS5的发布,固定定位据称支持移动版Safari。当然,这个说法不一定是真的,因为我会在下面给大家展示各种bug。顺便说一句,在iOS5的测试阶段,我已经上传了一些bug到苹果的bug报告工具,但是天知道这个工具是如何工作的,所以我不知道这些问题的数量(这里有争议,原文:the发行编号)。更新:基于CoreyDuston指出更多关于固定位置的错误,我添加了“滚动==不可用位置:固定元素”模块。位置:固定,谁在乎?我认为对于一个好的应用来说,没有必要使用固定定位。不过,我也注意到越来越多的iOS应用开始使用固定定位的工具栏,比如mini-MobileSafaris、AppleAppStore中的原生Facebook应用和Instagram。AppStore来自@devongovett,Facebook来自@9eggs问题我已经创建了一些示例页面供您自己查看。(以下视频来自Youtube,需要梯子)问题一:抖动如果以任何正常方式添加position:fixed到桌面级别的页面,滚动页面时会出现一定程度的抖动。视频链接:https://www.youtube.com/embed/yps8Ea5GO4I?fs=1&feature=oembed请注意,这个错误出现在模拟器上,但我也在真实的iPhone上捕获了相同的错误。模拟地址:http://jsbin.com/3/ixewok/6/问题2:滑动时无法更新数据。眼尖的朋友可能已经注意到,视频中的一些数值发生了变化。我监视了window.scrollTop和window.pageYOffset(还有下面提到的另一个值)。你会注意到这两个值只有在页面滚动完全停止后才会改变。当你想在地址簿应用程序中模拟bumping和shuntingheaders时,这是一个问题。(这句话翻译的不好,原文:如果你想监听页面位置来模拟类似地址簿app中类目标题的碰撞和分流等效果,这是一个问题。)问题3:如果位置漂移页面被放大到最大倍数。例如在iOS上,当用户将页面从竖屏旋转到横屏,再进行任意一个比例大于1(倍率放大)的缩放操作时,定位元素就会向上漂移。(我在其他网站看到元素完全飘出窗外)视频链接:https://www.youtube.com/embed/YIOdPf7jqK4?fs=1&feature=oembed模拟地址:http://jsbin.com/3/ixewok/6/问题四:获得焦点后跳转如果固定定位元素中有一个元素可以获得焦点,比如input元素,这可能会导致整个固定元素跳转到其他地方。只有当用户滑动页面时才会发生这种情况(如果那是你想要的,那就算了XD)。视频网址:https://www.youtube.com/embed/lrnvZDwgJRc?rel=0模拟网址:http://jsbin.com/3/ixewok/8/问题5:滚动==不可用位置:固定元素CoreyDutson指出还有另一个与修复相关的错误。尽管他的示例中的滚动是通过JavaScript完成的,但核心问题是:如果页面是通过脚本移动的,那么移动后固定定位的元素将无法使用。从我记录的屏幕截图中,您可以通过iWebInspector看到,尽管MobileSafari已将固定定位的元素渲染到位,但它实际上并不在应有的位置。当您再次触摸并移动页面时,实际元素会保持在正确的位置。视频地址:https://www.youtube.com/embed/R2MzdeJSCKw?fs=1&feature=oembed模拟地址:http://jsbin.com/3/ixewok/13/虽然我还没有找到解决这个bug的办法,而且我认为这可能是MobileSafari本身的渲染问题,但我会继续查看是否有解决方法。解决抖动随着iOS5的发布,MobileSafari也支持-webkit-overflow-scrolling:touch。这实际上是一个页面内容的内联块元素(我不知道这句话怎么翻译:我的意思是inlinerespecttothedocument)。如果我更改上一个示例中的css,并将html、body、content块的高度设置为100%,然后将滚动触摸属性应用于内容,抖动就会消失。但是,这并不能完全解决问题。一个巧妙的技巧是:确保用fixed定位的元素不是“移动画布”。此示例显示了一个固定元素放置在可滚动元素上方,但它不是DOM结构中可滚动元素的子元素。所以当我尝试在body元素上使用这个方法时,抖动问题仍然存在,因为fixed定位元素仍然在scroll元素内。视频地址:https://www.youtube.com/embed/suXz5dKtlcA?rel=0这个问题我也是在真机上拍的:点这里。模拟地址:http://jsbin.com/3/ixewok/10/再次更新滚动位置。细心的朋友应该也注意到了,有些值又变了。注意,由于我更改了CSS,body不再滚动,所以左右的0值分别对应window.scrollTop和window.pageYOffset。当窗口不可滑动时,内容块溢出,值不变。但是,content.scrollX的值仍在变化——但不是默认情况。首先,您需要添加触摸事件以在用户滑动(或触摸)时更新值,因此在JavaScript中我可以添加:content.ontouchstart=function(){};touch事件会发生在start,end,move三个阶段,而且只需要一个valueset(不好翻译:avalueset)。(请注意,我没有尝试直接将其设置为true-这也可能有效)。然而,这仍然不完美。正如您在上面的视频中看到的,该值仅在我触摸它时更新。当我将手指离开屏幕并让页面惯性滚动时,该值不会更新。我还是会继续尝试看看是否有可能获取值(不幸的是...)总结/TL;DR1,不要在滚动元素内部使用position:fixed,否则它会出现抖动错误并且看起来很糟糕(我见过比视频更疯狂抖动的情况)。2.确保使用-webkit-overflow-scrolling:touch3.如果要获取滚动的相关值,请确保在滚动元素上添加触摸监听事件。同时,请在其他移动浏览器中执行相同操作,而不仅仅是针对Apple。Apple虎头蛇尾的position:fixed真是让人头疼。这种风格真的很像一个巨人。2012年5月24日发布
