可滚动绝对定位div中相对定位的元素在滚动上“滞后”

时间:2013-02-25 17:33:23

标签: android html css cordova mobile

我有一个PhoneGap应用程序,显示一个很长的文本,包含我在Android上测试的标题,表格和图像。

除了样式为position:relative的元素外,一切正常 滚动时这些元素“滞后”,这意味着如果我滚动页面,那么这些元素会在大约四分之一秒后开始和结束滚动。

将绝对div与相对子项和具有overflow:auto的子项组合时会发生错误。删除任何这些东西都可以解决这个问题,但是我宁愿把它留下来。虽然我愿意删除它并单独显示它(如在对话框中),如果必须的话。

该错误仅出现在标准的Android浏览器上(当然还有我的PhoneGap应用程序)。 到目前为止,我已使用以下设备对其进行了测试:

  
      
  • 三星Galaxy Nexus(4.1.1)
  •   
  • 三星Galaxy S III(4.1.2)
  •   

感谢任何帮助,但我更喜欢不改变(或不太多)HTML和功能的解决方案。

after quick scrolling

我创建了一个显示错误的minimal example。只需在Android上打开它并开始滚动即可立即看到问题:

<!doctype html>
<html>
<head><meta name="viewport" content="initial-scale=1.0"></head>
<body style="margin:0">

<div style="position:absolute;overflow:auto;top:100px;bottom:100px;width:100%">

  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam a quam arcu. Duis ultrices mollis nibh ut hendrerit. Etiam a interdum metus. Integer volutpat, nibh laoreet euismod suscipit, libero sem iaculis lorem, ut hendrerit magna orci eu elit. Nulla eu ultricies libero. Nulla facilisi. Maecenas nec turpis vitae magna lobortis ornare sit amet ut lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc vestibulum lobortis orci, sit amet ornare dui congue nec. Morbi id magna at turpis auctor ultricies. Ut rhoncus quam augue, ut consectetur risus.</p>
  <div style="position:relative;background:red;">relative box<br>moves slower than the other text</div>
  <p>Fusce congue orci a nunc gravida sed pretium lorem convallis. Etiam hendrerit, ligula eget lobortis vestibulum, arcu sapien pharetra magna, auctor suscipit nisl tellus quis lacus. Cras id elit at ante mollis venenatis. Donec eu sollicitudin odio. Aliquam erat volutpat. Cras et tortor sed mi faucibus sagittis non quis metus. Morbi mauris ante, posuere vel rutrum id, mattis id enim. Morbi purus quam, euismod facilisis blandit quis, commodo at justo. Aliquam in fermentum nibh. Curabitur pharetra blandit risus sit amet tristique. Suspendisse potenti. Curabitur interdum eleifend justo, et dapibus justo volutpat sed.</p>          
  <div style="overflow:auto">
    <table>
      <tr><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th></tr>
      <tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>
    </table>
  </div>

</div>
</body>
</html>

4 个答案:

答案 0 :(得分:29)

简而言之,你所遭遇的弊病是常见的并有记载。 overflow:autooverflow:scroll的元素在桌面和移动浏览器中都会遇到绘制/重排/渲染问题。更重要的是,移动浏览器(iOS和Android上的webkit)存在问题,如果它们是“屏幕外”,则不会呈现相对和绝对元素。这会在屏幕上滚动时导致滞后。

您可以申请一些“黑客”垫片:

element {
    -webkit-overflow-scrolling: touch;
}

element > * {
    -webkit-transform: translateZ(0px);
}

element > * {
    -webkit-transform: translate3d(0,0,0);
}

为您阅读一些内容:

我从某处复制到我的笔记中的片段现在找不到来源:

  

特别是在严重依赖滚动的网站上,您可能会发现   您的主要内容依赖于溢出:滚动。这是真实的   挑战,因为这种滚动不是以任何方式加速GPU加速的   每当用户滚动时,内容都会重新绘制。你可以解决   使用普通页面滚动(溢出:可见)和   位置:固定

答案 1 :(得分:2)

我认为你有两个问题需要解决。下面滑落的文字和滞后的滚动速度?

我不确定您要对版权符号做什么,但我不会line-height小于11em。尝试使用父元素并设置其范围的样式。您可以在跨度上使用display:inline-block; vertical-align: middle;来获得所需的效果。

<p><span>&copy;</span>Some text</p>

滚动它取决于你在做什么。移动浏览器会在300ms个代码中等待<a>,以查看您是在滚动还是点击链接。它可能与此有关。如果是这样,我会结帐Google FastClick

移动浏览器可加速身体上的页面滚动。因此,使用嵌套的div或position:absolute可以防止您获得更快的滚动速度。在较新版本的AndroidiOS中,您可以使用-webkit-overflow-scrolling:touch来帮助,但这对旧款手机无效。我会尝试不使用绝对位置,因为根据你的例子,它看起来不像它的要求,也使用滚动的嵌套div需要一些用户在div内使用两个手指来滚动内容。我也会尝试避免这种情况,并将设计替换为更具移动性的设计模式,例如扩展内容的链接。

在尝试在移动设备上支持position:fixed时,很多滚动问题都会曝光,如果认为可能会导致它并且您想阅读它:http://bradfrostweb.com/blog/mobile/fixed-position/

答案 2 :(得分:1)

删除position:absoluteposition:relative,这种布局绝对不需要它们,并且会导致所有问题。

如果您愿意,可以在身体上添加一些margin-top

PhoneGap产生一些像这样的html垃圾,我希望你能很好地控制CSS。

答案 3 :(得分:0)

实际上有一个简单的CSS修复方法,在你的段落中添加position:relative来解决问题。

试试这个:

<!doctype html>
<html>
<head><meta name="viewport" content="initial-scale=1.0">
<style>
p{ position:relative;}
</style>
</head>
<body style="margin:0">

<div style="position:absolute;overflow:auto;top:100px;bottom:100px;width:100%">

  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam a quam arcu. Duis ultrices mollis nibh ut hendrerit. Etiam a interdum metus. Integer volutpat, nibh laoreet euismod suscipit, libero sem iaculis lorem, ut hendrerit magna orci eu elit. Nulla eu ultricies libero. Nulla facilisi. Maecenas nec turpis vitae magna lobortis ornare sit amet ut lacus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nunc vestibulum lobortis orci, sit amet ornare dui congue nec. Morbi id magna at turpis auctor ultricies. Ut rhoncus quam augue, ut consectetur risus.</p>
  <div style="position:relative;background:red;">relative box<br>moves slower than the other text</div>
  <p>Fusce congue orci a nunc gravida sed pretium lorem convallis. Etiam hendrerit, ligula eget lobortis vestibulum, arcu sapien pharetra magna, auctor suscipit nisl tellus quis lacus. Cras id elit at ante mollis venenatis. Donec eu sollicitudin odio. Aliquam erat volutpat. Cras et tortor sed mi faucibus sagittis non quis metus. Morbi mauris ante, posuere vel rutrum id, mattis id enim. Morbi purus quam, euismod facilisis blandit quis, commodo at justo. Aliquam in fermentum nibh. Curabitur pharetra blandit risus sit amet tristique. Suspendisse potenti. Curabitur interdum eleifend justo, et dapibus justo volutpat sed.</p>          
  <div style="overflow:auto">
    <table>
      <tr><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th>    <th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th><th>test</th>    <th>test</th><th>test</th><th>test</th><th>test</th><th>test</th></tr>
      <tr><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td>    <td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td><td>test</td>    <td>test</td><td>test</td><td>test</td><td>test</td><td>test</td></tr>
    </table>
  </div>

</div>
</body>
</html>