简体   繁体   English

jQuery“前进” css动画后无法为div制作动画

[英]JQuery unable to animate div after “forwards” css animation

See example http://jsfiddle.net/nxsv5dgw/ 参见示例http://jsfiddle.net/nxsv5dgw/

Div appears on stage, a "forwards" animation occurs on it, JQuery can apparently no longer "animate" the properties that were animated. Div出现在舞台上,在其上出现“前进”动画,JQuery显然不再能够“动画化”动画的属性。

In the example, a css animation plays on the width of a box. 在示例中,css动画在方框的宽度上播放。 OnClick, a JQuery animation tries to shrink the width and height of the box, but only the height is changed. OnClick是一种JQuery动画,它试图缩小框的宽度和高度,但只更改高度。 Here's the code. 这是代码。

$(".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;}
}

Is there any way to circumvent this? 有什么办法可以避免这种情况? I'd rather avoid doing all animations in JQuery if possible. 如果可能,我宁愿避免在JQuery中进行所有动画处理。

Only tested for Firefox, but working - I've adjusted your Fiddle adding 仅针对Firefox进行了测试,但可以正常使用-我已调整了您的Fiddle添加

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

to the click-function. 点击功能。 This sets the width to the actual width and overrides the animation, but I think there could be a better solution as it looks like a hack. 这会将宽度设置为实际宽度并覆盖动画,但是我认为可能有更好的解决方案,因为它看起来像hack。

Update - also working for Safari and IE. 更新-也适用于Safari和IE。

Actually you can set the width to 500px after the animation is complete so that DOM element knows that DIV has width 500px and remove the css animation from Element. 实际上,您可以在动画完成后将宽度设置为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);
    });
});

Basic Idea: To avoid conflicting between CSS animation and jQuery animation one should call the jQuery animation only when CSS animation is completed by using animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd event and by undoing the rules overriden by CSS animation and removing animation from the element. 基本思想:为避免CSS动画和jQuery动画之间发生冲突,只有在CSS动画完成后,才应调用jQuery动画,方法是使用animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd事件,并撤消CSS动画覆盖的规则并从元素中删除动画。

Working Fiddle 工作小提琴

As you said, this happens by using forward in animation. 如您所说,这是通过在动画中使用forward发生的。

From the CSS Animations Working Draft 来自CSS动画工作草案

CSS Animations affect computed property values. CSS动画会影响计算的属性值。 During the execution of an animation, the computed value for a property is controlled by the animation. 在动画执行期间,属性的计算值由动画控制。 This overrides the value specified in the normal styling system. 这将覆盖普通样式系统中指定的值。 Animations override all normal rules, but are overriden by !important rules. 动画会覆盖所有常规规则,但会被!important规则覆盖。

and Animation Duration 动画时长

[…] and an animation that fills forwards will retain the value specified at the 100% keyframe, even if the animation was instantaneous. […]和向前填充的动画将保留在100%关键帧处指定的值,即使该动画是瞬时的也是如此。 Also, animation events are still fired. 此外,动画事件仍会触发。

So, it cannot be overriden by default, except for !important rules. 因此,默认情况下不能覆盖它,除非!important规则。 But this cannot be done using jQuery.animate() 但这无法使用jQuery.animate()

I'd rather avoid doing all animations in JQuery if possible. 如果可能,我宁愿避免在JQuery中进行所有动画处理。

I guess that you can't. 我猜你不能。

You could use a jQuery solution: 您可以使用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> 

I'm not sure if this is an option, as the effect is slightly different then what you are aiming for, but I just wanted to put it out there as an alternative. 我不确定这是否是一种选择,因为效果与您要达到的目的略有不同,但我只是想将其作为替代方案。

The problem is clearly caused by the fact that ( http://w3.org/TR/css3-animations/#animations ) 问题显然是由以下事实引起的:( http://w3.org/TR/css3-animations/#animations

Animations override all normal rules, but are overriden by !important rules 动画会覆盖所有常规规则,但会被!important规则覆盖

Therefore you could try to animate the scale transform in stead. 因此,您可以尝试对scale转换进行动画处理 This way you are not altering the properties that have been set trough the animation. 这样,您就不会更改通过动画设置的属性。 jQuery does not support it out of the box, but this plugin adds the functionality: https://github.com/rstacruz/jquery.transit . jQuery不立即提供支持,但此插件添加了以下功能: https : //github.com/rstacruz/jquery.transit

This also has the huge added advantage of being much better for performance then animating your width an height, as very well explained here: http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/ 这还有一个巨大的附加优势,那就是性能要好得多,然后将宽度和高度动画化,如下所述: http : //www.html5rocks.com/en/tutorials/speed/high-performance-animations/

The drawback of this method is that the contents of your div is scaled down as well , which may not be the desired effect. 这种方法的缺点是div内容也会按比例缩小 ,这可能不是理想的效果。

I've set up a demo to demonstrate: http://jsfiddle.net/nxsv5dgw/13/ 我已经建立了一个演示来演示: http : //jsfiddle.net/nxsv5dgw/13/

And the code: 和代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM