jQuery + Animate.css animation only working once,

2019-02-13 04:59发布

I'm trying to reproduce a specific animation each time a button is pressed.

Specifically, I'm using jQuery and the animate.css library for this effect: on button click, a class is added (two classes to be precise: fadeInDown animated) to the element I want to animate.

The animation does work correctly, but only once. Why is this?

Fiddle: http://jsfiddle.net/jqm4vjLj/2/

I want the animation to reset every time I click the button, even if it is halfway through completion from a previous click. It should also work whenever I click the button, not only once.

JS:

$("#button").click(function () {
    $("#button").removeClass();
    $("#button").addClass("fadeInDown animated");
});

Classes from animate.css:

@-webkit-keyframes fadeInDown {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-20px);
    transform: translateY(-20px);
  }

  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}

@keyframes fadeInDown {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-20px);
    -ms-transform: translateY(-20px);
    transform: translateY(-20px);
  }

  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
}

.fadeInDown {
  -webkit-animation-name: fadeInDown;
  animation-name: fadeInDown;
}

.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}

7条回答
成全新的幸福
2楼-- · 2019-02-13 05:30

A much safer approach will be use the animation end event like

$("#button").click(function() {
  $("#button").addClass("fadeInDown animated").one('animationend webkitAnimationEnd oAnimationEnd', function() {
    $("#button").removeClass();
  });
});
#button {
  height: 30px;
  width: 120px;
  border: 1px solid black;
}
.animated {
  -webkit-animation-duration: 1s;
  animation-duration: 1s;
}
@-webkit-keyframes fadeInDown {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-20px);
    transform: translateY(-20px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
    transform: translateY(0);
  }
}
@keyframes fadeInDown {
  0% {
    opacity: 0;
    -webkit-transform: translateY(-20px);
    -ms-transform: translateY(-20px);
    transform: translateY(-20px);
  }
  100% {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
}
.fadeInDown {
  -webkit-animation-name: fadeInDown;
  animation-name: fadeInDown;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="button"></div>

查看更多
Rolldiameter
3楼-- · 2019-02-13 05:31

See http://css-tricks.com/restart-css-animation/, which discusses this exact problem.

I think the cleanest solution is to wrap the functionality of removing the element and re-inserting it in the same position in the HTML tree in a global function. Then, when you want to restart an animation, you just remove the class, call the reset function (grabbing the newly-inserted element from the return value), and then add the animation class(es) back to start the animation again.

For example:

function reset($elem) {
    $elem.before($elem.clone(true));
    var $newElem = $elem.prev();
    $elem.remove();
    return $newElem;
} // end reset()

$("#button").click(function () {
    var $this = $(this);
    $this.removeClass();
    $this = reset($this);
    $this.addClass("fadeInDown animated");
});

http://jsfiddle.net/jqm4vjLj/6/

This solution provides maximum responsiveness, since the old in-progress animation is automatically ended when the animating element is destroyed, and the newly-inserted element's animation begins immediately.

查看更多
啃猪蹄的小仙女
4楼-- · 2019-02-13 05:42

You need to remove class after the animation is complete,

but directly using removeClass wont work, because it will not let animation complete, instead use setTimeout

see this http://jsfiddle.net/jqm4vjLj/4/

   $("#button").click(function () {

        $("#button").addClass("fadeInDown animated");
        setTimeout(function(){ $("#button").removeClass("fadeInDown animated");},100)
    });
查看更多
何必那么认真
5楼-- · 2019-02-13 05:43

The simple solution for me is to start reflow process before adding class. You can do it for example by "change" width of element. I think reflow process is faster for browser then node reinserting. And its simpler in terms of coding. In jQuery:

$(this)
  .removeClass('myAnimation')
  .width('auto') // the magic
  .addClass('myAnimation')
查看更多
成全新的幸福
6楼-- · 2019-02-13 05:56

Problem is it immediately remove class and then add class so I just added new div with button2 id and on its click it just remove class and then click again on button div it would animate.

so problem is you need to do it after completion of animation.

$("#button1").click(function () {
    $("#button").removeClass();
});

fiddle is here: http://jsfiddle.net/jqm4vjLj/5/

查看更多
趁早两清
7楼-- · 2019-02-13 05:56

This works for me, from the animate.css github:

animateCss: function (animationName) {
    var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
    $(this).addClass('animated ' + animationName).one(animationEnd, function() {
        $(this).removeClass('animated ' + animationName);
    });
}
查看更多
登录 后发表回答