Issues with position fixed & scroll(移动端 fixed 和 scroll 问题)
转载请注明英文原文及译文出处
原文地址:Issues with position fixed & scrolling on iOS
原文作者:Remy Sharp
译文地址:移动端 fixed 和 scroll 问题
译文作者:鎏金圣手火麒麟
最近在做iOS端的H5页面时,遇到了一个定位问题:
1、position: fixed 元素在页面滚动时属性值变为absolute,在页面停止滚动瞬间,才恢复fixed;
2、当使用 fixed 定位的元素,存在于进行滚动的容器元素内时,拖动容器元素会使出现闪动问题。
在寻求解决方案的过程中,看到了这一篇文章,对这个问题的原因解释得不错,故翻译过来,供大家参考。
翻译的过程中,对原文小标题做了修改,方便大家阅读。
翻译不对的地方,也可以在评论中帮忙指出,谢谢。
以下是译文:
随着iOS 5的发布,fixed 定位据说将会支持移动端Safari。
当然,这个说法并不一定是真的,因为在下文中我将给大家展示各种各样的bug。
顺带一提,在iOS 5的测试阶段,我已经向苹果的bug报告工具上传了一些bug,但天知道这个工具是怎么运行的,所以我不知道这些问题的编号(此处有争议,原文:the issue numbers)。
更新:基于 Corey Duston 指出关于 position fixed 的更多bug,我已经添加了 "scrolling == unusable position:fixed element"模块。
position:fixed, who cares?
我认为对于一个好的app而言,不一定非要使用到 fixed 定位。但是,我也注意到有越来越多的 iOS app 开始使用 fixed 定位的工具栏,比如 mini-MobileSafaris,苹果应用商店的原生 Facebook app 和 Instagram。
AppStore via @devongovett, Facebook via @9eggs
问题
我已经创建了一些示例页面,方便大家自行查看。(以下视频来自油管,需要梯子)
问题1:抖动
如果你将 position: fixed
用任何正常的方式添加到桌面级页面中,你就会在滑动页面的时候,看到一定程度的抖动问题。
视频链接:https://www.youtube.com/embed/yps8Ea5GO4I?fs=1&feature=oembed
请注意这是在模拟器上出现了该bug,但我同样在 iPhone 真机上捕获了相同的bug。
模拟地址:http://jsbin.com/3/ixewok/6/
问题2:滑动时无法更新数据
眼尖的小伙伴可能已经发现了视频中的某些值发生了变化。我监控了 window.scrollTop
和 window.pageYOffset
(还有另一个值将会在下文提到)。你会注意到这两个值只有在页面滑动完全停止后才会发生变化。
当你想要在通讯录APP中模拟碰撞和分流式头部目录时,这就是个问题了。
(这句翻译的不好,原文:This is a problem if you want to monitor the page position to simulate effects like the bumping and shunting of category headings like you might see in the address book app.)
问题3:位置漂移
如果页面被放大到最大倍数,比如在 iOS 上,当用户将页面从纵向旋转到横向后,再进行任何比例超过1的缩放操作(比例放大),定位元素就会向上漂移。(我曾在其他网站见过元素彻底漂移出视窗的情况)
视频链接:https://www.youtube.com/embed/YIOdPf7jqK4?fs=1&feature=oembed
模拟地址:http://jsbin.com/3/ixewok/6/
问题4:获取焦点后跳跃
如果在 fixed 定位的元素中存在一个可以获取焦点的元素,比如 input 元素,这就有可能导致整个 fixed 元素跳到其他地方。这种情况只会在用户滑动页面的时候出现(如果这正是你想要的效果,那当我没说 XD)。
视频地址:https://www.youtube.com/embed/lrnvZDwgJRc?rel=0
模拟地址:http://jsbin.com/3/ixewok/8/
问题5:Scrolling == 无法使用的 position: fixed 元素
Corey Dutson指出还有另一个与 fixed 有关的bug。尽管在他的示例中滚动是通过JavaScript来实现,但核心问题是:如果页面是由脚本控制移动,那么在移动之后,fixed 定位的元素将不可使用。
从截屏中我已经做了记录,你可以通过iWebInspector看到,尽管 MobileSafari 已经在位置上渲染了 fixed 定位的元素,但它实际上并不在应该在的位置。当你再次触碰和移动页面时,真正的元素才会保持在正确的位置上。
视频地址:https://www.youtube.com/embed/R2MzdeJSCKw?fs=1&feature=oembed
模拟地址:http://jsbin.com/3/ixewok/13/
尽管我还没有找到这个bug的解决办法,并且我觉得可能这是 MobileSafari 自身的渲染问题,不过我还是会继续看看是否有办法解决。
解决抖动
随着 iOS 5 的发布,MobileSafari 同样支持了 -webkit-overflow-scrolling: touch
。这实际上是用于页面内容的行内块元素(这句不知如何翻译:I mean inline with respect to the document)。
如果我在前文的示例中改变 css,并且设置 html、body、内容块的高度为100%,然后将 scrolling touch 属性应用到内容上,那么抖动就会消失了。然而,这并不能彻底解决问题。
有个巧妙的办法是这样的:确保使用 fixed 定位的元素不是一个“移动画布”。这个示例展示了一个 fixed 元素放置在一个滚动元素的上方,但在dom结构中,它并不是滚动元素的子级。
所以当我尝试将这个办法用在 body
元素上时,抖动问题还是存在,因为 fixed 定位元素仍然位于滚动元素内。
视频地址: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三个阶段,并且只需要一个值集(翻译的不好:a value set)。
(请注意,我并没有尝试直接将其设置为 true
——这可能也能起作用)。
然而,这依然是不完美的。你可以在上面的视频中看到,值只会在我触摸的时候更新。当我的手指离开屏幕,让页面惯性滚动时,值就不会更新了。
我仍会继续尝试有没有可能获取该值(无奈……)
总结 / TL;DR
1、不要在滚动元素内部使用 position: fixed
,否则它会出现抖动bug并且看起来很糟糕(我曾见过比视频中抖动得更疯狂的情况)。
2、确保使用 -webkit-overflow-scrolling: touch
3、如果你想要获取 scroll 的相关值,请确保你在滚动元素上添加了 touch 的监听事件。
同时,请在其他移动端浏览器也这么处理,不要只对苹果做这些处理。苹果对于 position: fixed
虎头蛇尾的做法真让人头疼,这作风跟巨硬真像。
Posted 24-May 2012
Issues with position fixed & scroll(移动端 fixed 和 scroll 问题)的更多相关文章
- web移动端fixed布局和input等表单的爱恨情仇 - 终极BUG,完美解决
[问题]移动端开发,ios下当fixed属性和输入框input(这里不限于input,只要可以调用移动端输入法的都包括,如:textarea.HTML5中contenteditable等),同时存在的 ...
- 【转载】Web移动端Fixed布局的解决方案
特别声明:本文转载于EFE的<Web移动端Fixed布局的解决方案>.如需转载,烦请注明原文出处:http://efe.baidu.com/blog/mobile-fixed-layout ...
- web移动端Fixed在Input获取焦点时ios下产生的BUG及处理
1.现象 可以看到下面两张图,图1搜索框为fixed固定在顶部,滚动没有任何问题. 图2当光标进入搜索框时,ios自作聪明的把光标定位到中间,并且fixed属性被自动修改成了absolute.此时注意 ...
- position 的值absolute、fixed、relative和static的定位原点是什么
position 的值absolute.fixed.relative和static的定位原点是什么 absolute 成绝对定位的元素,相对于值不为static的第一个父元素进行定位,也可以理解为离自 ...
- 微软BI 之SSIS 系列 - 平面文件格式的区别(Delimited,Fixed width,Ragged Right, Fixed width ...)
开篇介绍 SSIS 中处理文件,一般在描述输出平面文件格式的时候通常会出现以下几种选项: Delimited - 默认输出列使用逗号分隔,也可以选择其它的诸如 | ,或者 Tab 等. Fixed W ...
- Web移动端Fixed布局的解决方案
移动端业务开发,iOS 下经常会有 fixed 元素和输入框(input 元素)同时存在的情况. 但是 fixed 元素在有软键盘唤起的情况下,会出现许多莫名其妙的问题. 这篇文章里就提供一个简单的有 ...
- [转] Web移动端Fixed布局的解决方案
移动端业务开发,iOS 下经常会有 fixed 元素和输入框(input 元素)同时存在的情况. 但是 fixed 元素在有软键盘唤起的情况下,会出现许多莫名其妙的问题. 这篇文章里就提供一个简单的有 ...
- 八、Web移动端Fixed布局的解决方案
移动端业务开发,iOS 下经常会有 fixed 元素和输入框(input 元素)同时存在的情况. 但是 fixed 元素在有软键盘唤起的情况下,会出现许多莫名其妙的问题. 这篇文章里就提供一个简单的有 ...
- 移动端fixed兼容问题
最近做移动端页面,有个需求类似下图 底部导航用fixed定位时在部分iOS版本中会有问题: 1.上滑是底部会跟着滑动,手指松开时才会又回到底部 2.软键盘唤起的情况下,也会出现许多莫名其妙的问题 网上 ...
随机推荐
- Linux-本地日志服务管理(rsyslog基础)
目录 系统环境 1.常见的两种日志管理服务 1.1 RSYSLOG系统日志服务 1.2 ELK 2.RSYSLOG日志服务的相关知识 2.1 RSYSLOG日志消息级别 2.2 RSYSLOG日志服务 ...
- laravel 根据字段不同值做不同查询
在开发过程中我们经常遇到这种情况: 例如,一个信息表message,字段type 1.操作提醒 2.平台通知,表message_read记录当信息是平台通知时用户浏览状况 那么 当信息是平台通知时是针 ...
- Linux常用文件管理命令详解
cat cat命令用于连接文件并打印到标准输出设备上. 命令语法:cat [参数] [文件名] 参数说明: 参数 说明 -n 由1开始对所有输出的行数进行编号. -b 由1开始对所有输出的行数进行编号 ...
- tensorflow源码解析之distributed_runtime
本篇主要介绍TF的分布式运行时的基本概念.为了对TF的分布式运行机制有一个大致的了解,我们先结合/tensorflow/core/protobuf中的文件给出对TF分布式集群的初步理解,然后介绍/te ...
- spring源码干货分享-对象创建详细解析(set注入和初始化)
记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea 建议:学习过程中要开着源码一步一步过 Spring根据BeanDe ...
- 面试题详解:如何用Redis实现分布式锁?
说一道常见面试题: 使用Redis分布式锁的详细方案是什么? 一个很简单的答案就是去使用 Redission 客户端.Redission 中的锁方案就是 Redis 分布式锁的比较完美的详细方案. 那 ...
- Azure DevOps (四) 创建第一条流水线
前几篇文章,我们记录了一下azure代码仓库的使用,这篇开始,我们来搞一下azure的流水线. 流水线这个东西我觉得是devops中对于开发人员的灵魂组件,只要我们配置好了一次,剩下的所有部署都是自动 ...
- 浏览器输入URL,按下回车后发生什么?
大致流程 URL 解析 DNS 查询 TCP 连接 服务器处理请求 浏览器接受响应 浏览器解析渲染页面 断开连接
- 【elasticsearch】搜索过程详解
elasticsearch 搜索过程详解 本文基于elasticsearch8.1.在es搜索中,经常会使用索引+星号,采用时间戳来进行搜索,比如aaaa-*在es中是怎么处理这类请求的呢?是对匹配的 ...
- C 如何将输出的地址转化为十进制数
•需求 这两天在看内存对齐的相关问题,因此产生了一个,如何将地址转换为十进制数? 对于如下程序: void func() { int a = 10; printf("a 的地址为:%p\n& ...