基本的JS动画在Safari中无法正常工作

时间:2013-08-31 12:23:58

标签: javascript css safari

所以这是我的动画功能:

    function animation(el, isHorizontal, from, to, callback) {
        var start = true === isHorizontal ? from.x : from.y,
            stop = true === isHorizontal ? to.x : to.y,
            intervalId, diff;

        intervalId = setInterval(function () {
            diff = Math.abs(stop - start);
            if (stop < start) {
                if (diff < 4) {
                    start -= diff;
                } else {
                    start -= 4;
                }
            } else {
                if (diff < 4) {
                    start += diff;
                } else {
                    start += 4;
                }
            }
            if (true === isHorizontal) {
                el.style.left = start + 'px';
            } else {
                el.style.top = start + 'px';
            }
            if (start === stop) {
                clearInterval(intervalId);
                callback();
            }
        }, 1);
    }

它在Chrome中完美运行,虽然在Safari中,动画元素似乎在它们应该停止之前停止了几个像素。

假设我要从左边移动:8向左移动:116。在Safari中,元素在左边结束:108,当我打开Inspector查看控制台并检查左边偏移是否正确时元素,元素正确地重新定位。

我需要做的就是打开开发人员控制台,元素跳转到正确的位置。

太奇怪了。

以下是我可能相关的一些CSS:

.box {
    position: relative;
     }
    .item {
        position: absolute;
        background-position: left top;
        background-repeat: no-repeat;
        background-size: 100% auto;
        -webkit-transform: transform;
    }

2 个答案:

答案 0 :(得分:1)

您的代码看起来没有任何问题,但是Safari应该在它应该执行重绘时(因为当您打开开发人员控制台时问题就会消失)。

如果将1ms间隔增加到50ms,你仍然会遇到问题吗?

通常有效的一种方法是强制浏览器通过在动画结束时在主体上切换虚拟类来重绘整个页面:

if (start === stop) {
    jQuery("body").toggleClass("forceRepaint");

    clearInterval(intervalId);
    callback();
}

你可以在没有jQuery的情况下做到这一点,但它会更简洁。

此外,如果你对这样的动画使用requestAnimationFrame()而不是setInterval()(以及更好的性能),你很可能会避免这个问题。在旧浏览器中有几个polyfill可以回退到setInterval / setTimeout。

答案 1 :(得分:0)

所以在Safari中我似乎必须触发硬件加速,否则Safari无法跟上并快速重绘图像:

    -webkit-transform-style: preserve-3d;
    .item {
        position: absolute;
        background-position: left top;
        background-repeat: no-repeat;
        background-size: 100% auto;
        -webkit-transform-style: preserve-3d;
    }