【问题标题】:JQuery unable to animate div after "forwards" css animationJQuery在“转发”css动画后无法为div设置动画
【发布时间】:2014-12-25 08:13:19
【问题描述】:

查看示例 http://jsfiddle.net/nxsv5dgw/

Div 出现在舞台上,出现“向前”动画,JQuery 显然不能再“动画”被动画的属性。

在示例中,css 动画在框的宽度上播放。 OnClick,一个 JQuery 动画试图缩小盒子的宽度和高度,但只改变了高度。这是代码。

$(".a").click(function(e) {
  $(this).animate({
    width: "-=100px", // doesn't work after CSS animation
    height: "-=100px",
  }, 400); 
})

.a {
  background:red;
  position:absolute;
  height:500px;
  width:600px;
  animation: anim 0.4s forwards 1s;
}

@keyframes anim {
  0% {width:600px;}
  100% {width:500px;}
}

有什么办法可以规避吗?如果可能的话,我宁愿避免在 JQuery 中做所有动画。

【问题讨论】:

  • 你不想使用 jQuery,但你已经在使用它了?
  • w3.org/TR/css3-animations/#animations. Animations override all normal rules, but are overriden by !important rules
  • @ericbelldesigns 对了,我想尽量少用JQuery。

标签: javascript jquery html css animation


【解决方案1】:

仅针对 Firefox 进行了测试,但可以正常工作 - 我已调整您的 Fiddle 添加

$(this).css({
    "width": $(this).width(),
    "animation": "none"
});

点击功能。这会将宽度设置为实际宽度并覆盖动画,但我认为可能有更好的解决方案,因为它看起来像一个 hack。

更新 - 也适用于 Safari 和 IE。

【讨论】:

  • 如果元素在css动画完成之前被点击,会不会和元素的css动画冲突?
  • @GauravKalyan 感谢您的提及。是的,确实如此,也许这不是一个可以忽略的小细节(尽管对于示例动画,您必须非常快速地单击)。因此我写道,可能有一个更清洁的解决方案,并且在动画结束后添加点击事件(就像你在回答中所做的那样)对我来说似乎是更清洁的方式。
  • 感谢您的澄清 :)
【解决方案2】:

其实你可以在动画完成后设置宽度为500px,这样DOM元素就知道DIV的宽度为500px,然后从Element中移除css动画。

$(".a").on("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", function () {
    $(this).width(500);
    $(this).css({
            "animation": "none"
        });
    $(".a").click(function (e) {
        $(this).animate({
            width: "-=100px",
            height: "-=100px",
        }, 400);
    });
});

基本思路: 为了避免 CSS 动画和 jQuery 动画之间的冲突,只有在 CSS 动画完成时才调用 jQuery 动画,方法是使用 animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd 事件并撤消 CSS 动画覆盖的规则和从元素中移除动画。

Working Fiddle

【讨论】:

  • 请注意:使用.on() 比使用.bind() 更好。后者已被弃用。
【解决方案3】:

正如您所说,这是通过在动画中使用 forward 来实现的。

来自CSS Animations Working Draft

CSS 动画影响计算的属性值。在动画执行期间,属性的计算值由动画控制。这会覆盖在正常样式系统中指定的值。动画会覆盖所有常规规则,但会被 !important 规则覆盖。

Animation Duration

[...] 和向前填充的动画将保留在 100% 关键帧处指定的值,即使动画是瞬时的。此外,仍然会触发动画事件。

因此,默认情况下它不能被覆盖,除了 !important 规则。但是这个cannot be done使用jQuery.animate()

如果可能,我宁愿避免在 JQuery 中制作所有动画。

我猜你不能。

您可以使用 jQuery 解决方案:

$(document).ready(function() {
  $('.a').delay(1000).animate({
    width: "-=100px"    
  }, 400);
  
});

$(".a").click(function(e) {
  $(this).animate({
    width: "-=100px", // doesn't work after CSS animation
    height: "-=100px",
  }, 400); 
})
.a {
  background:red;
  position:absolute;
  height:500px;
  width:600px;  
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="a"></div>

【讨论】:

    【解决方案4】:

    我不确定这是否是一个选项,因为效果与您的目标略有不同,但我只是想把它作为替代方案。

    问题显然是由 (http://w3.org/TR/css3-animations/#animations) 引起的

    动画会覆盖所有常规规则,但会被 !important 覆盖 规则

    因此,您可以尝试scale 变换设置动画。这样您就不会更改通过动画设置的属性。 jQuery 不支持开箱即用,但这个插件添加了功能:https://github.com/rstacruz/jquery.transit

    这还有一个巨大的附加优势,即性能要好得多,然后为您的宽度和高度设置动画,这里有很好的解释:http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

    这种方法的缺点是你的div的内容也被缩小了,这可能不是你想要的效果。

    我设置了一个演示来演示:http://jsfiddle.net/nxsv5dgw/13/

    还有代码:

    $(".a").click(function (e) {
        $(this).transition({
            scale: '-=0.1'
        }, 4000);
    });
    

    【讨论】:

      猜你喜欢
      • 2012-04-04
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      • 2016-04-08
      相关资源
      最近更新 更多