如何在使用Webkit转换和转换时修复闪烁

gar*_*uan 19 html css safari webkit

我有一个非常简单的演示工作,它使用Webkit转换和转换来实现'面板'(div)之间的平滑水平滚动.

我想要走这条路线而不是Javascript驱动系统的原因是它适用于iPad和Javascript性能相当差,但css转换和过渡是如丝绸一样平滑.可悲的是,我用我的演示在iPad上闪烁了很多.

你可以在这里看到演示

你需要safari或iPad才能看到它的实际效果.我从来没有在转换和转换的任何演示中看到过这种情况,所以我希望这是可以修复的.

无论如何这里的代码是为了这个东西....

HTML看起来像这样.

<html>
    <head>
        <title>Swipe Demo</title>
        <link href="test.css" rel="stylesheet" />
        <link href="styles.css" rel="stylesheet" />
        <script type="text/javascript" src="jquery.js"></script>
        <script type="text/javascript" src="functions.js"></script>
        <script type="text/javascript" src="swiping.js"></script>
    </head>
    <body>


    <div id="wrapper">
        <div class='panel one'>
            <h1>This is panel 1</h1>
        </div>

        <div class='panel two'>
            <h1>This is panel 2</h1>
        </div>

        <div class='panel three'>
            <h1>This is panel 3</h1>
        </div>

        <div class='panel four'>
            <h1>This is panel 4</h1>
        </div>
    </div>

    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

CSS看起来像这样

    body,
    html
        {
            padding: 0;
            margin: 0;
            background: #000;
        }

    #wrapper
        {
            width: 10000px;
            -webkit-transform: translateX(0px);
        }

    .panel
        {
            width: 1024px;
            height: 300px;
            background: #fff;
            display: block;
            float: left;
            position: relative;
        }
Run Code Online (Sandbox Code Playgroud)

而javascript看起来像这样

// Mouse / iPad Touch
var touchSupport = (typeof Touch == "object"),
touchstart   = touchSupport ? 'touchstart' : 'mousedown',
touchmove    = touchSupport ? 'touchmove'  : 'mousemove',
touchend     = touchSupport ? 'touchend'   : 'mouseup';

$(document).ready(function(){

    // set top and left to zero
    $("#wrapper").css("top", 0);
    $("#wrapper").css("left", 0);

    // get total number of panels
    var panelTotal;
    $(".panel").each(function(){ panelTotal += 1 });

    // Touch Start
    // ------------------------------------------------------------------------------------------

    var touchStartX;
    var touchStartY;
    var currentX;
    var currentY;
    var shouldMove = false;
    document.addEventListener(touchstart, swipeStart, false);
    function swipeStart(event){

        touch = realEventType(event);

        touchStartX = touch.pageX;
        touchStartY = touch.pageY; 
        var pos = $("#wrapper").position();
        currentX = parseInt(pos.left);
        currentY = parseInt(pos.top);

        shouldMove = true;

    }

    // Touch Move
    // ------------------------------------------------------------------------------------------

    var touchMoveX;
    var touchMoveY;
    var distanceX;
    var distanceY;
    document.addEventListener(touchmove, swipeMove, false);
    function swipeMove(event){
        if(shouldMove){
            touch = realEventType(event);
            event.preventDefault();

            touchMoveX = touch.pageX;
            touchMoveY = touch.pageY;

            distanceX = touchMoveX - touchStartX;
            distanceY = touchMoveY - touchStartY;       
            movePanels(distanceX);

        }
    }

    function movePanels(distance){
        newX = currentX + (distance/4);    
        $("#wrapper").css("left", newX);
    }


    // Touch End
    // ------------------------------------------------------------------------------------------

    var cutOff = 100;
    var panelIndex = 0;
    document.addEventListener(touchend, swipeEnd, false);
    function swipeEnd(event){

        touch = (touchSupport) ? event.changedTouches[0] : event;

        var touchEndX = touch.pageX;
        var touchEndY = touch.pageY;

        updatePanelIndex(distanceX);

        gotToPanel();

        shouldMove = false;

    }

    // --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --

    function updatePanelIndex(distance){

        if(distanceX > cutOff)
            panelIndex -= 1;

        if(distanceX < (cutOff * -1)){
            panelIndex += 1;
        }

        if(panelIndex < 0){
            panelIndex = 0;
        }

        if(panelIndex >= panelTotal)
            panelIndex = panelTotal -1;

            console.log(panelIndex);

    }

    // --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --

    function gotToPanel(){

        var panelPos = getTotalWidthOfElement($(".panel")) * panelIndex * -1;

        $("#wrapper").css("-webkit-transition-property", "translateX");
        $("#wrapper").css("-webkit-transition-duration", "1s");
        $("#wrapper").css("-webkit-transform", "translateX("+panelPos+"px)");

    }

});

function realEventType(event){
    e = (touchSupport) ? event.targetTouches[0] : event;
    return e;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*her 45

@gargantaun是对的,如果你想要动画的元素大于屏幕,Webkit就会闪烁.但是有一个简单的解决方法.只需添加:

-webkit-backface-visibility: hidden;
Run Code Online (Sandbox Code Playgroud)

元素,你很高兴!

  • 使用风险自负!当IOS7问世时,我们的应用程序因内存错误而崩溃.它通常使用10-15 MB,但IOS崩溃日志报告使用~600 MB.经过一番挖掘后,事实证明这个背面可见性黑客(我们确实从源代码中链接到这个SO线程)是原因,或者至少是删除它导致崩溃消失.不知道为什么,它只是IOS7.我认为必须有一些内存泄漏错误或苹果公司的Webkit分支中的东西.很多开发者都在抱怨IOS7 Safari崩溃了. (9认同)
  • Upvoted!哇,iOS7 Safari真的坏了...... (2认同)

Nat*_*e T 9

尝试使用translate3d而不是translateX.看起来只有translate3d是iPad 3.2上的硬件加速.


gar*_*uan 5

如上所述,最好使用Translate3d,因为硬件加速可以实现更平滑的过渡.

但是,当动画的div大于屏幕时,会引起闪烁.所以,如果你有一个区域,你希望水平转换的屏幕宽度最多为3.5,它应该被分成4个像这样的div

[1] [2] [3] [.5]

所有div都不应超过屏幕高度或宽度.

对于发布此答案的迟到感到抱歉.在我得到一个"热门问题"的通知之前,我完全忘了它.