-->

移动Webkit的回流问题(Mobile Webkit reflow issue)

2019-06-26 00:07发布

我一直在经历着的WebKit移动版本的问题(特别是Webkit的534.46在iOS 5.1.1移动Safari浏览器,现在iOS版Chrome)不上,我见过的任何桌面浏览器发生。 (即低于演示应的webkit的移动版本进行查看。)

这是问题的一个活生生的例子。 在CSS的核心是非常直截了当。 它定位在页面的左侧有一个字母索引:

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

当一个元素是在身体上固定位置的问题发生。 它是完全能够与之交互直到滚动的变化,然后将其停止接受输入。 如果I(手动地)轻摇滚动甚至一个象素那么再次变为活动状态。 该示例保持尽可能简单,并且不使用任何JavaScript。 真正锤打它之后,我发现它出现的元素认为它滚动,但已经在视觉上固定。 换句话说,如果你点击“A”然后试着点击“A”再次,有时你会得到第二次的点击中,但将进一步拉列表。 这似乎是一个CSS回流问题给我。 我知道,移动的WebKit试图减少回流的数量。

这里是解决办法的一个活生生的例子。

我可以用JS迫使整个文档的CSS回流上滚动(与防止这样的事情发生,直到100毫秒滚动后,油门),这似乎在简单的例子来解决此问题。 不幸的是,这不利于这一问题的现实版本。

这是问题的页面和解决方法的脚本代码。

我的问题是这里发生了什么,是有,我很想念一个CSS解决方法吗? 具体而言,我很好奇,如果任何CSS大师可以找出布局的情况是什么,防止点击击中固定件上的正确位置? 更好地了解可能有助于找到真正的解决。

编辑:我忘了提的例子明确强制视口窗口的大小。 因此,用户不能放大/缩小,这意味着该位置是:固定锚应的元素窗口的左侧。

更新(2012年9月20日):这似乎是固定在移动Safari在iOS 6(以及UIWebView中)。 任何解决方法应先检查,以确保它是在iOS <6。例如,使用CssUserAgent这将是这样的:

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

Answer 1:

实际上解决了我的具体问题的答案是找到了解决方案的变化在@保罗Sweatte的一个链接 :

本质上,一个普通的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);


Answer 2:

讽刺的是,我原来的回流修复(在这个问题挂)在我的真正的应用程序现在工作了。 在此情况下,把它的一个变种是给别人用。 它可以被称为任何容器元素,或者如果没有在通过它重排整个文档。

var forceReflow = function(elem){
    elem = elem || document.documentElement;

    // force a reflow by increasing size 1px
    var width = elem.style.width,
        px = elem.offsetWidth+1;

    elem.style.width = px+'px';

    setTimeout(function(){
        // undo resize, unfortunately forces another reflow
        elem.style.width = width;
        elem = null;
    }, 0);
};

关于这样做的好处是,它不需要创建/添加/移除元素,只需要调整容器。



Answer 3:

我安装iWebInspector的是相当破获的权利,但与的jsfiddle乱搞后和iOS的SIM好像你的预感是正确的 - 尽管是位置:固定,浏览器认为该页面滚动和螺钉了点击目标。

它看起来很像,这是相同的问题iOS的Safari浏览器:固定定位的元素内锚只能使用一次 ,这也一直没有解决纯CSS。 同时相关: 固定位置导航栏只可点击在移动Safari浏览器上的iOS5一次 。

四角切圆,我敢肯定,它已经已经注意到了,这是不可能的滚动左侧,所以在iPhone上的指数只显示AM。



Answer 4:

看起来这是一个已知的错误 :

核心问题是:如果页编程移动(即,用户没有引起滚动)的修复元件内的元素是不可用的。

使用绝对定位, 改变的标记 ,或使用混合动力的一个解决方法 。



Answer 5:

这里的McKamey的解决方法的变化。 它避免了回流两次,可以用(取决于您的应用程序)闪烁帮助:

setTimeout(function(){
    document.body.style.borderBottom = 
        document.body.style.borderBottom === 'none' ? '1px solid white' : 'none';
}, 0);


Answer 6:

我相信这是更好的,达到同样的效果,使链接在固定的页脚点击。 不知怎么的,做urlbar藏身导致在固定的页脚链接,直到您滚动一点点无法点击。 重点投入时,我已经看到了这也和我附加一个事件处理所有焦点事件触发此关为好。 我这样做是有道场附加的事件。

        if(navigator.userAgent.match(/iPhone/i)){
        /* The famous iOS can't-click-links until touch fix, I attach onfocus */
            query('input,textarea,select', this.domNode).on('focus', function(el){
                document.documentElement.style.paddingRight = '1px';
                setTimeout(function () {
                document.documentElement.style.paddingRight = '';
                }, 0);
            });
        }


文章来源: Mobile Webkit reflow issue