Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS animation triggered through JS only plays every other click

I want to make a simple JavaScript onclick animation. My problem is that when I click onto the button, the animation is executed, but when I click again onto the button, nothing happens. On the third clicks the animation plays again. I want to make that, the animation plays at the second click. Heres my code"

var anim = document.getElementById("anim");

anim.onclick = function highA() {

    var willCheck = document.getElementById("contactId");
    if (!willCheck.classList.contains("highAnim")) {
        willCheck.classList.add("highAnim");
    } else {
        willCheck.classList.remove("highAnim");
    }
}
#contactId { background: red;}

.highAnim {
    background-color: var(--white);
    animation-name: highcheck;
    animation-duration: 0.35s;
    animation-timing-function: ease-in-out;
}

@keyframes highcheck {
    0% {transform: rotate(0);}
    25% {transform: rotate(1deg);}
    50% {transform: rotate(2deg);}
    75% {transform: rotate(1deg);}
    100% {transform: rotate(0);}
}
<a onclick="anim()" id="anim">Click</a><br><br>
<div id="contactId">Some Text</div>
like image 433
scrummy Avatar asked Jan 10 '21 13:01

scrummy


1 Answers

The issue is because the first click adds the class and triggers the animation, yet the second (and every even numbered click) after that removes the class so nothing happens.

To fix this you can use the animationend event to remove the class automatically after the animation has ended. That way when you next click again the class is added to the element once more and the animation plays. Try this:

var anim = document.getElementById("anim");
var willCheck = document.getElementById("contactId");

anim.addEventListener('click', () => {
  willCheck.classList.add("highAnim");
});

willCheck.addEventListener('animationend', () => {
  willCheck.classList.remove("highAnim");
});
#contactId { background: red; }

.highAnim {
  background-color: var(--white);
  animation-name: highcheck;
  animation-duration: 0.35s;
  animation-timing-function: ease-in-out;
}

@keyframes highcheck {
  0% { transform: rotate(0); }   
  50% { transform: rotate(2deg); }
  100% { transform: rotate(0); }
}
<a id="anim">Click</a><br><br>
<div id="contactId">Some Text</div>

Note that I removed the 25% and 75% items in the animation as it's a linear motion from 0% to 50% and back again, so they are not needed. This also helps to make the animation smoother.

like image 176
Rory McCrossan Avatar answered Sep 19 '22 08:09

Rory McCrossan