1

I know that it is possible to set the animation of an element by id either in a stylesheet or in JS from the DOM. The issue is that I want the animation to execute every time a click action on a specific element is performed by the user. Adding the animation to an element's style in JS seems to add it permanently so that the keyframes animation cannot be performed again, (only performed once when the window finishes loading). I also thought about using jQuery's .animate() function however all documentation points to it animating over CSS specific styles and not setting/calling the animation style attribute as if I were to set it using CSS. I want to know the best way of executing my animation over an element when another element is clicked on by the user and consistently executing the animation for each click.

@keyframes fadeInDown {
  from {
   opacity: 0;
   transform: translate(0, -20%);
 }
 to {
   opacity: 1;
   transform: translate(0, 0);
 }
}

The current way I'm setting animation for an element:

$("#element").css("animation", "fadeInDown 0.5s ease-in 0s 1");

4 Answers 4

2

This is a toggling animation using transition and jquery, without using .animate()

$(document).ready(function() {
  $('button').click(function() {
    var box = $('.box')
    box.removeClass("show")
    setTimeout(function(){
        box.addClass("trans").addClass("show")
        setTimeout(function(){
            box.removeClass("trans")
        },100)
    },200)
  });
});
.box {
  background: red;
  height: 50px;
  width: 50px;
  position: absolute;
  margin-top: 50px;
  margin-left: 50px;
  opacity: 0;
  transform: translate(0, -20%);
}

.box.trans {
  transition: all 0.7s;
}

.box.show {
  opacity: 1;
  transform: translate(0, 0);
}
<button>Test</button>
<div class="box show"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Sign up to request clarification or add additional context in comments.

7 Comments

This is better, however, I am aware that toggling the class removes and in this case would hide the red square in your example with a fadeout and slideup transition. However I don't exactly want to toggle the class (or might just want to change the transition animation). Every time the test button is clicked the red square should immediately set opacity first without showing a translation and then after doing so, add the show class back to the element. I hope that's not too confusing to understand.
As a followup the red square should never show a fadeout/slideup, it should always show a fadein/slidedown.
Its all very confusing indeed. But I think this is what you are looking for.
That's getting closer to what I want. Basically instead of toggling the test button, when you click test it needs to remove the show class and then add immediately. Basically all in one fluid motion.
Let me get it clear. So initially, .box will be visible to user. Then button is clicked. Box disappeared immediately and appear with slideDown+fadeIn. Is that it?
|
1

It's my first answer on stack overflow. I had the same question about animation.

What I did last was just like Vivek Patel's answer, but instead of toggling the css keyframe, I created a separated class only for css animation("animation-fadeInDown"), and toggle it.

Because the animation-name "fadeInDown" is correponding to the @keyframes name, so if you separate it you could apply the animation to other elements, by just toggling the animation class.

And, you can still do the css deco to the original box seperately, which might be more clear to read.

I hope this is close to what you looking for.

$('button').click(() => {
  $('.box').toggleClass('animation-fadeInDown');
});
.box {
  width: 50px;
  height: 50px;
  background: black;
}

.animation-fadeInDown {
  animation: fadeInDown 0.5s ease-in 0s 1
}

@keyframes fadeInDown {
    from {
      opacity: 0;
      transform: translate(0, -20%);
    }
    to {
      opacity: 1;
      transform: translate(0, 0);
    }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box"></div>
<button>
    Test
</button>

Comments

0

Basically CSS animation only runs once when the page loads. So it is not possible to re-trigger it again. Here is the workaround for your use case: Remove the element from the page entirely and re-insert it.

Try this:

$('button').click(() => {
  var oldDiv = $('#animated-div');
  newDiv = oldDiv.clone(true);

 	oldDiv.before(newDiv);

	$("." + oldDiv.attr("class") + ":last").remove();
});
@keyframes fadeInDown {
    from {
      opacity: 0;
      transform: translate(0, -20%);
    }
    to {
      opacity: 1;
      transform: translate(0, 0);
    }
}

.animated-div {
  animation: fadeInDown 0.5s ease-in 0s 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="animated-div" class="animated-div" style="width: 50px; height: 50px; background: black"></div>
<button>
Test
</button>

2 Comments

I see that this will work but is there a better way to do this sort of functionality without removing and reinserting elements? For example, is there a way to remove the animation from CSS after it executes with some type of listener function? (Doing this synchronously)
I think it will not be possible. I also tried to remove the class and again adding the class in setTimeout() like below: $('#animated-div').removeClass("animated-div"); setTimeout(() => { $('#animated-div').addClass("animated-div") }); But I think the above approach of removing/reinserting is better.
0

This is an simple example that use jquery to animate in Queue as it works in @keyframes. The transition duration and animation duration gives more control on the animation character.

$(document).ready(function() {
  $('button').click(function() {
    $('.box')
      .css('transition', 'all 0.2s')
      .animate({ opacity: 0 }, {
        duration: 200,
        step: function(now) {
          $(this).css({ opacity: now });
          $(this).css({ transform: 'translate(0, -20%)' });
        }
      })
      .animate({ opacity: 1 }, {
        duration: 600,
        step: function(now) {
          $(this).css({ opacity: now });
          $(this).css({ transform: 'translate(0, 0)' });
        }
      })
  });
});
.box {
  background: red;
  height: 50px;
  width: 50px;
  position: absolute;
  margin-top: 50px;
  margin-left: 50px;
}
<button>Test</button>
<div class="box"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

6 Comments

This is using only Transitions. That means, there is no animation happening without initiating it with jquery.
Also, this animation jumps up and down on button click where I just want the elements to fadein and slide down at the same time.
Do you need the button to toggle or just animation happen only once?
I'm a little confused by the question. Basically I want the animation I created in @keyframes to be executed on an element each time a button is clicked. Meaning that the elements that are being animated will fadein and slide down at the same time every time the button is clicked. I did this before and it worked only once when the webpage loaded but wouldn't execute the animation again on the button click. I can do it with transitions instead but I need the transition to replicate the animation I created.
that is the character of animation in css. You need to use transitions for proper control of the way elements move. See my other answer. It is also less code.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.