【问题标题】:CSS animation bug in SafariSafari 中的 CSS 动画错误
【发布时间】:2018-03-21 23:35:08
【问题描述】:

我有一个延迟的 CSS 动画,我在延迟期间暂停了它。 它在 Firefox 和 Chrome 上按预期工作,“你好”不动。 但是在 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 添加关键帧,我可以使这个简单的示例工作。然而,我的真实案例有多个与延迟同步的动画。

【问题讨论】:

  • 无法重现。在 Safari 11.0 (macOS) 中,它按预期工作。
  • @Styx 我刚刚在 Safari 11.0 中进行了测试,但错误仍然存​​在。 “你好”会跳到底部而不是被暂停。
  • 试试这个jsfiddle,请:jsfiddle.net/iStyx/2uqf1p9y
  • 超时时间必须设置为 1000 才能重现错误。
  • 我玩过这个东西很多,但似乎没有解决方法:(

标签: javascript css animation safari webkit


【解决方案1】:

只有当超时设置为小于动画延迟的值时,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>

尝试不同的超时值以查看它是否正常工作。不能说为什么会这样。对我来说似乎是一个错误。在 OS X El Capitan 10.11.6 / Safari 11.0 (11604.1.38.1.7) 上测试。

Codepen demo

【讨论】:

  • 谢谢。我也得出结论,这是一个错误,特别是因为我发现了其他错误。 Safari 的动画似乎令人难以置信。我想我必须用 Javascript 重写所有内容。
【解决方案2】:

这不是问题的答案。但是,如果您删除动画延迟,则暂停和重新启动动画会正常工作。看来动画延迟是导致问题的原因。也许与其依靠 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>

【讨论】:

  • 谢谢。是的,我注意到了。我找到了另一种解决方法,我删除了延迟并添加了关键帧和不同的动画。
  • 我还注意到您的代码在移动版 Safari 9.0 上无法正常工作。文本前后移动。
  • 是的,在动画播放状态和 safari 方面肯定存在一些错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-29
  • 2018-03-01
  • 1970-01-01
  • 2018-04-05
  • 2015-08-17
  • 1970-01-01
  • 2018-04-03
相关资源
最近更新 更多