复杂的Webkit Bug?相对定位 + Z-Index + 溢出隐藏 + CSS3变换

7
以下代码(JSFiddle预览)在Webkit浏览器中与其他现代浏览器相比产生了意外的结果:
<script type="text/javascript">
jQuery(document).ready(function($) {
    RunFunction();

    $('.ColorSquare').click(function() {
        $('#Lightbox').css('display','block');
        $('#ShowColorSquare').css('display','block');
        $('#ShowColorSquare').css('z-index','10');
        $('#ShowColorSquare').css('left',$('#ShowColorSquare').parent().width() / 2 - 50);
        $('#ShowColorSquare').css('top',$('#ShowColorSquare').parent().height() / 2 - 50);
        $('#ShowColorSquare').html('The color is: ' + $(this).css('background-color'));
    });
    $('#ShowColorSquare').click(function() {
        $('#Lightbox').css('display','none');
        $('#ShowColorSquare').css('display','none');
        $('#ShowColorSquare').html('');
    });
    $('#Lightbox').click(function() {
        $('#Lightbox').css('display','none');
        $('#ShowColorSquare').css('display','none');
        $('#ShowColorSquare').html('');
    });
});
function RunFunction() {
    $('#slide1').animate({
        left: '-=310'
    }, 3000);
    $('#slide2').animate({
        left: '-=310'
    }, 3000);
    $('#slide3').animate({
        left: '-=310'
    }, 3000, function() {
        if($('#slide1').css("left") == '-310px') {
            $('#slide1').css("left",620);
        }
        if($('#slide2').css("left") == '-310px') {
            $('#slide2').css("left",620);
        }
        if($('#slide3').css("left") == '-310px') {
            $('#slide3').css("left",620);
        }   
        RunFunction(); 
    });
}
</script>
<style>
#Spin {
    width:50px;
    height:50px;
    margin: 15px 0px 15px 15px;
    background-color:#960;
    animation-name:Spin;
    animation-duration:5s;
    transform-origin:50% 50%;
    animation-iteration-count:infinite;

    -webkit-animation-name:Spin;
    -webkit-animation-duration:5s;
    -webkit-transform-origin:50% 50%;
    -webkit-animation-iteration-count:infinite;
}
@keyframes Spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}
@-webkit-keyframes Spin {
    0% { -webkit-transform: rotate(0deg); }
    100% { -webkit-transform: rotate(360deg); }
}
.ColorSquare {
    height:100px;
    width:100px;
    position:absolute;
}
#ShowColorSquare {
    height:100px;
    width:100px;
    position:absolute;
    background-color:white;
    display:none;
}
#Lightbox {
    background-color:#000;
    width:100%;
    height:100%;
    position:fixed;
    top:0px;
    left:0px;
    opacity:.8;
    display:none;
    z-index:5;
}
.Panel {
    width:225px;
    height:250px;
    position:absolute;
    background-color:#6C6C6C;
}
</style>

<div id="Spin"></div>

<div style="height:260px;width:500px;overflow-x:hidden;background:#CCC;">
    <div style="height:250px;width:500px;position:relative;">
        <div id="slide1" class="Panel" style="top:0px;left:0px;">
            <div>Slide 1</div>
            <div style="position:relative;margin-top:10px;width:225px;height:200px;">
                <div class="ColorSquare" style="background-color:#093;left:0px;top:0px;"></div>
                <div class="ColorSquare" style="background-color:#C9F;left:100px;top:100px;"></div>
            </div>
        </div>
        <div id="slide2" class="Panel" style="top:0px;left:310px;">
            <div>Slide 2</div>
            <div style="position:relative;margin-top:10px;width:225px;height:200px;">
                <div class="ColorSquare" style="background-color:#CF9;left:0px;top:0px;"></div>
                <div class="ColorSquare" style="background-color:#C63;left:100px;top:100px;"></div>
            </div>
        </div>
        <div id="slide3" class="Panel" style="top:0px;left:620px;">
            <div>Slide 3</div>
            <div style="position:relative;margin-top:10px;width:225px;height:200px;">
                <div class="ColorSquare" style="background-color:#696;left:0px;top:0px;"></div>
                <div class="ColorSquare" style="background-color:#F96;left:100px;top:100px;"></div>
            </div>
        </div>
        <div id="ShowColorSquare"></div>
    </div>
</div>
<div id="Lightbox"></div>

预期结果:应该有3个DIV(幻灯片)连续循环向左动画,包括幻灯片内的彩色框。如果单击一个彩色框,则显示带有所单击彩色框的RBG颜色的灯箱。再次单击以关闭灯箱。同时,在浅灰色父DIV之前应用3D变换,具有相对位置和溢出隐藏,并在绝对定位幻灯片DIV上使用Jquery动画。
Webkit中的结果:在桌面上调整浏览器窗口大小或单击JSFiddle面板调整大小手柄(或捏/缩放)之前,幻灯片内的彩色框似乎根本不移动/渲染。在另一个调试注意事项上,如果3D变换动画没有循环,当动画停止时,DIV将按预期呈现。
显示Webkit错误的测试结果:
  • Win7 IE10: 通过
  • Win7 Chrome: 通过
  • Win7 FF: 通过
  • Win7 Safari: 失败
  • Win8 IE11: 通过
  • Android Chrome: 失败
  • iOS Safari: 失败
  • iOS Chrome: 失败
  • MacOS Safari: 失败
  • MacOS Chrome: 失败

注意 (JSFiddle 预览) 没有3D变换,代码可以正常工作,但在桌面上动画不太流畅。 lightbox 可以正常工作。

注意 (JSFiddle 预览) 在父DIV后进行3D变换,动画很流畅,lightbox 可以正常工作。

注意:(JSFiddle预览)应用于具有溢出的父DIV的 -webkit-transform:rotate(0deg),在平板电脑上动画会出现卡顿,但是3D变换可以存在于父DIV之前或幻灯片DIV中。然而,另一个问题也会随之产生。父溢出DIV的z-index低于灯箱,使得黑色灯箱DIV出现在位于父DIV内部的白色对话框DIV上方。

我知道这是一个非常奇怪的例子,但它是更私密复杂代码的简化版本。 3D变换必须在父DIV之前或幻灯片内部。灯箱对话框必须在父DIV或幻灯片内部,但要显示在黑色灯箱DIV上方,而黑色灯箱DIV不能在父DIV内部,因为溢出隐藏不会使黑色灯箱DIV充满整个浏览器屏幕。

感谢任何帮助。


1
在我的 OS X 上,Chrome 28 可以运行,但 Safari 6 不行。 - insertusernamehere
有人有像insertusernamehere这样不同的测试用例吗? - detailCode
我相信较新版本的Chrome正在逐渐远离webkit。这就解释了为什么上个月Win7 Chrome出现故障,而现在已经可以正常工作了。 - detailCode
1
Chrome刚刚从Webkit中分离出Blink,所以他们肯定还没有修复这个错误。我也意识到Gecko在渲染动画方面非常糟糕:( - Ian Clark
2个回答

4
如果您阅读了Chrome中的GPU加速合成http://www.chromium.org/developers/design-documents/gpu-accelerated-compositing-in-chrome,您会发现当以下情况之一时,渲染层将获得自己的合成层:
  1. 图层具有3D或透视变换CSS属性
  2. 视频元素使用加速视频解码使用该图层
  3. 画布元素使用3D或2D上下文使用该图层
  4. 图层使用CSS动画进行不透明度或使用动画webkit转换
  5. 图层具有具有合成层的后代
  6. 图层具有具有合成层的较低z-index兄弟(换句话说,该图层在合成层上方呈现)
添加或删除3D变换时会得到不同的结果,因为代码会通过GPU加速路径或软件渲染路径。 GPU加速路径非常敏感于您拥有的GPU /驱动程序,如果您看到任何奇怪的图形故障,则首先应检查的一件事是在chrome:// flags /中关闭硬件加速时它们是否仍然存在。
在Chrome OSX上,这三个示例对我都有效,因此这很可能是特定图形卡的浏览器错误。如果您可以找到一个基本情况,我建议向chromium项目报告此错误并提供您的GPU信息。

0

我认为硬件加速可能是问题所在...

你可以看一下这个问题和被接受的答案...

看这里

尝试使用chrome://gpu命令,并查找差异...


桌面版Chrome浏览器的新版本运行良好。旧版本的Webkit和移动浏览器是问题所在。 - detailCode

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接