Safari中的CSS动画bug

18

我有一个带延迟的CSS动画,并在延迟期间暂停它。 在Firefox和Chrome上,它按预期工作,“Hello”不会移动。 但是在Safari上,动画会跳到最后一帧。 为什么会这样,如何解决?

function test() {
  var timeout = 1000;
  setTimeout(function() {
    document.getElementById('animation').style.animationPlayState = 'paused';
  }, timeout);
}

document.addEventListener("DOMContentLoaded", test);
#animation {
  animation: test 2s linear 2s;
}

@keyframes test {
  to {
    transform: translateY(100px);
  }
}
<div id="animation">
  Hello (this text should not move)
</div>

如果我去掉2秒的延迟,将持续时间设置为4秒,并添加一个transform:none的关键帧,我可以使这个简单的例子工作。然而我的真实情况有多个动画与延迟同步。


@Styx 我刚在 Safari 11.0 上测试了一下,这个 bug 仍然存在。"Hello" 跳到底部而不是暂停。 - Patrick
请尝试这个jsfiddle链接:https://jsfiddle.net/iStyx/2uqf1p9y/ - Styx
超时时间必须设置为1000才能重现该错误。 - Patrick
那么它会在动画开始之前暂停吗? - Styx
1
我已经尝试了很多次,但似乎没有任何解决方法 :( - Styx
显示剩余3条评论
2个回答

12

当超时时间小于动画延迟时,Safari 行为存在问题。因此,一种解决方法是通过 animation-play-state 将初始状态设置为 paused,然后通过 JS 控制它,如下所示:

function test() {
  let el = document.getElementById("animation");
  let timeout = 1000;
  
  // Get the delay. No luck with el.style.animationDelay
  let delay =
    window
      .getComputedStyle(el)
      .getPropertyValue("animation-delay")
      .slice(0, -1) * 1000;

  // Only resume and later pause when timeout is greater than animation delay
  if (timeout > delay) {
    el.style.animationPlayState = "running";
    setTimeout(function() {
      el.style.animationPlayState = "paused";
    }, timeout);
  }
}

document.addEventListener("DOMContentLoaded", test);
#animation {
  animation: test 2s linear 3s;
  animation-play-state: paused; /* Pause it right after you set it */
}

@keyframes test {
  to {
    transform: translateY(100px);
  }
}
<div id="animation">
  Hello (this text should not move)
</div>

尝试使用不同的超时时间来查看它的工作情况。虽然不知道为什么会这样,但我认为这似乎是一个 bug。在 OS X El Capitan 10.11.6 / Safari 11.0 (11604.1.38.1.7) 上进行了测试。

CodePen 示例


谢谢。我也得出结论这是一个错误,特别是因为我找到了其他的错误。Safari在动画方面似乎非常有漏洞。我想我必须用Javascript重新制作一切。 - Patrick

4

这不是解决问题的答案。然而,如果您删除动画延迟,则暂停和重新启动动画将按预期工作。看起来动画延迟是导致问题的原因。也许不要依赖CSS处理延迟,可以使用JavaScript编程控制动画延迟。

请参见下面的动画暂停和运行示例:

function test() {
  var timeout = 1000;
  setTimeout(function() {
    document.getElementById('animation').style.animationPlayState ='paused';
    document.getElementById('animation').style.webkitAnimationPlayState ='paused';
  }, timeout);
  setTimeout(function() {
    document.getElementById('animation').style.animationPlayState='running';
    document.getElementById('animation').style.webkitAnimationPlayState ='running';
  }, timeout * 2);
}

document.addEventListener("DOMContentLoaded", test);
#animation {
    -webkit-animation: test 2s linear;
        animation: test 2s linear;
}

@-webkit-keyframes test {
  to {
    -webkit-transform: translateY(100px);
        transform: translateY(100px);
  }
}

@keyframes test {
  to {
    -webkit-transform: translateY(100px);
        transform: translateY(100px);
  }
}
<div id="animation">
  Hello (this text should not move)
</div>


谢谢。是的,我注意到了。我找到了另一个解决方法,我删除了延迟并添加了关键帧和不同的动画。 - Patrick
我还注意到你的代码在移动版Safari 9.0上无法正常工作。文本会来回移动。 - Patrick
1
是的,关于动画播放状态和Safari肯定存在一些错误。 - wlh

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