一尘不染

移动Webkit重排问题

css

我一直在移动版本的Webkit(尤其是iOS 5.1.1上的Webkit
534.46,作为移动Safari,现在是iOS的Chrome)上遇到问题,在我所看到的任何台式机浏览器上都没有发生。
(即,以下演示应在移动版本的Webkit上查看。)

[这是该问题的现场示例CSS的核心非常简单。它在页面左侧放置字母索引:

#index {
    left:0; margin:0; padding:0; position:fixed; top:0; width:3em;
}

当元素在主体顶部上方的固定位置时,就会发生此问题。它完全可以与之交互,直到滚动发生变化,然后它停止接受输入。如果我(手动)摇动滚动条甚至一个像素,那么滚动条将再次变为活动状态。该示例保持尽可能简单,并且不使用任何JavaScript。真正敲击之后,我发现该元素似乎认为它已滚动但已在视觉上固定。换句话说,如果您单击“
A”,然后再次尝试单击“ A”,有时您将获得第二次单击,但它会在列表的下方。在我看来,这似乎是CSS回流问题。我知道移动Webkit试图减少重排次数。

我能够使用JS强制整个文档的CSS在滚动时进行重排(使用油门防止滚动发生,直到滚动后100ms为止),这在简单示例中似乎可以解决此问题。不幸的是,这无助于此问题的实际版本。

我的问题是这里发生了什么,我是否缺少CSS解决方法?
具体来说,我很好奇是否有CSS专家可以弄清楚是什么布局情况阻止了点击次数到达固定元素的正确位置?更好的理解可能有助于找到真正的解决方案。

编辑: 我忘了提到该示例显式强制视口为窗口的大小。因此,用户无法放大/缩小,这意味着position:fixed应该将元素锚定到窗口的左侧。

更新(2012-09-20): 这似乎已在iOS 6(以及UIWebView)的MobileSafari中修复。任何解决方法都应首先检查以确保它在iOS<6上。例如,使用CssUserAgent如下所示:

if (parseFloat(cssua.ua.ios) < 6) { /* ... */ }

阅读 270

收藏
2020-05-16

共1个答案

一尘不染

实际解决了我的特定问题的答案是@PaulSweatte的链接之一中找到的一种解决方案的变体:

本质上,添加了一个比身体更高的普通div。移除后,它会使主体有效滚动或回流。将添加/删除之间的延迟设置为0ms足以允许DOM重新计算而不会引起任何闪烁。这是我可以找到的最小脚本,它可以完全解决此问题的
特定 实例position:fixed上所有元素的问题。 __

var hack = document.createElement("div");
hack.style.height = "101%";
document.body.appendChild(hack);
setTimeout(function(){
    document.body.removeChild(hack);
    hack = null;
}, 0);
2020-05-16