[Solved] Multiple animations for 1 element JS, CSS [closed]


The Issue

The issue is caused by multiple eventListener’s being attached to the same object. Specifically:

  • function2 starts an animation on object2 and attaches an animationend listener to object2
  • function5 starts an animation on object2 and attaches an animationend listener to object2 (the 2nd event listener on object2)
  • when the animation in function5() completes the event listeners from function2 and function5 are both called
  • the callback functions from the event listeners in function2 and function5 cause new animationend events to trigger, causing function3 and function6 to be called.
  • this causes a multiple animation sequences to start, which then multiply

I’ve added some console.logs to the demo below to help visualize this.

object1 = document.getElementById("object1");
object2 = document.getElementById("object2");
object3 = document.getElementById("object3");
object4 = document.getElementById("object4");
object5 = document.getElementById("object5");
object6 = document.getElementById("object6");
object7 = document.getElementById("object7");
object8 = document.getElementById("object8");
object9 = document.getElementById("object9");
object10 = document.getElementById("object10");

function function1() {
  console.log('animation 1 - start')
  object5.style.animation = "animation1 2s ease 0s 1 normal forwards running";
  object5.addEventListener("animationend", function() {
    console.log('animation 1 - end')
    function2()
  });
}

function function2() {
  console.log('animation 2 - start')
  object2.style.animation = "animation2 2s ease 0s 1 normal forwards running";
  object2.addEventListener("animationend", function() {
    console.log('animation 2 - end')
    function3()
  });
}

function function3() {
  console.log('animation 3 - start')
  object5.style.animation = "animation3 2s ease 0s 1 normal forwards running";
  object5.addEventListener("animationend", function() {
    console.log('animation 3 - end')
    function4()
  });
}

function function4() {
  console.log('animation 4 - start')
  object10.style.animation = "animation4 2s ease 0s 1 normal forwards running";
  object10.addEventListener("animationend", function() {
    console.log('animation 4 - end')
    function5()
  });
}

function function5() {
  console.log('animation 5 - start')
  object2.style.animation = "animation5 2s ease 0s 1 normal forwards running";
  object2.addEventListener("animationend", function() {
    console.log('animation 5 - end')
    function6()
  });
}

function function6() {
  console.log('animation 6 - start')
  object5.style.animation = "animation6 2s ease 0s 1 normal forwards running";
  object5.addEventListener("animationend", function() {
    console.log('animation 6 - end')
    function7()
  });
}

function function7() {
  console.log('animation 7 - start')
  object8.style.animation = "animation7 2s ease 0s 1 normal forwards running";
  object8.addEventListener("animationend", function() {
    console.log('animation 7 - end')
    function8()
  });
}

function function8() {
  console.log('animation 8 - start')
  object5.style.animation = "animation8 2s ease 0s 1 normal forwards running";
  object5.addEventListener("animationend", function() {
    console.log('animation 8 - end')
    function9()
  });
}

function function9() {
  object4.style.animation = "animation9 2s ease 0s 1 normal forwards running";

}
#object1 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: blue;
  float: left;
}

#object2 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: green;
  float: left;
  animation-iteration-count: 2;
}

#object3 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: red;
  float: left;
}

#object4 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: purple;
  float: left;
}

#object5 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: orange;
  float: left;
}

#object6 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: brown;
  float: left;
}

#object7 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: pink;
  float: left;
}

#object8 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: tomato;
  float: left;
}

#object9 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: indigo;
  float: left;
}

#object10 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: mediumspringgreen;
  float: left;
}

#vacuum {
  height: 200px;
}

#vacuum2 {
  height: 1000px;
  width: 100px;
  float: left;
}

button {
  height: 50px;
  width: 65px;
  background-color: crimson;
  color: white;
  border-radius: 2px;
  margin-left: 60px;
}

@keyframes animation1 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  33% {
    transform: translateY(-70px) translateX(0px);
  }
  66% {
    transform: translateY(-70px) translateX(-200px);
  }
  100% {
    transform: translateY(-70px) translateX(-150px);
  }
}

@keyframes animation2 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  100% {
    transform: translateY(70px) translateX(0px);
  }
}

@keyframes animation3 {
  0% {
    transform: translateY(-70px) translateX(-150px);
  }
  100% {
    transform: translateY(-70px) translateX(250px);
  }
}

@keyframes animation4 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  33% {
    transform: translateY(70px) translateX(0px);
  }
  66% {
    transform: translateY(70px) translateX(-400px);
  }
  100% {
    transform: translateY(0px) translateX(-400px);
  }
}

@keyframes animation5 {
  0% {
    transform: translateY(70px) translateX(0px);
  }
  50% {
    transform: translateY(70px) translateX(400px);
  }
  100% {
    transform: translateY(0px) translateX(400px);
  }
}

@keyframes animation6 {
  0% {
    transform: translateY(-70px) translateX(250px);
  }
  50% {
    transform: translateY(-70px) translateX(200px);
  }
  100% {
    transform: translateY(-70px) translateX(150px);
  }
}

@keyframes animation7 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  100% {
    transform: translateY(70px) translateX(0px);
  }
}

@keyframes animation8 {
  0% {
    transform: translateY(-70px) translateX(-200px);
  }
  50% {
    transform: translateY(-70px) translateX(-150px);
  }
  100% {
    transform: translateY(-70px) translateX(-100px);
  }
}

@keyframes animation9 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  100% {
    transform: translateY(70px) translateX(0px);
  }
}

@keyframes animation10 {
  0% {
    transform: translateY(70px) translateX(0px);
  }
  50% {
    transform: translateY(70px) translateX(-250px);
  }
  100% {
    transform: translateY(0px) translateX(-250px);
  }
}

@keyframes animation11 {
  0% {
    transform: translateY(70px) translateX(0px);
  }
  50% {
    transform: translateY(70px) translateX(250px);
  }
  100% {
    transform: translateY(0px) translateX(250px);
  }
}
<div id="vacuum"></div>
<div id="vacuum2"></div>
<div id="object1"></div>
<div id="object2"></div>
<div id="object3"></div>
<div id="object4"></div>
<div id="object5"></div>
<div id="object6"></div>
<div id="object7"></div>
<div id="object8"></div>
<div id="object9"></div>
<div id="object10"></div>
<button onclick="function1()">Click Mom :)</button>

The Solution

The solution is to removeEventListeners from the objects to prevent the previous functions from being called when later animationend events occur.

For example, to remove the function2 event listener from object5:

function function2() {
  object5.removeEventListener('animationend', function2);
  object2.style.animation = "animation2 2s ease 0s 1 normal forwards running";
  object2.addEventListener("animationend", function3);
}

Or, if you want to be more general, you can use the event.target.removeEventListener(event.type, arguments.callee) format, like:

function function2(event) {
  event.target.removeEventListener(event.type, arguments.callee);
  object2.style.animation = "animation2 2s ease 0s 1 normal forwards running";
  object2.addEventListener("animationend", function3);
}

Here’s the working solution:

object1 = document.getElementById("object1");
object2 = document.getElementById("object2");
object3 = document.getElementById("object3");
object4 = document.getElementById("object4");
object5 = document.getElementById("object5");
object6 = document.getElementById("object6");
object7 = document.getElementById("object7");
object8 = document.getElementById("object8");
object9 = document.getElementById("object9");
object10 = document.getElementById("object10");

function function1() {
  object5.style.animation = "animation1 2s ease 1 normal running 0s forwards";
  object5.addEventListener("animationend", function2);
}

function function2(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object2.style.animation = "animation2 2s ease 1 normal running 0s forwards";
  object2.addEventListener("animationend", function3);
}

function function3(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object5.style.animation = "animation3 2s ease 1 normal running 0s forwards";
  object5.addEventListener("animationend", function4);
}

function function4(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object10.style.animation = "animation4 2s ease 1 normal running 0s forwards";
  object10.addEventListener("animationend", function5);
}

function function5(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object2.style.animation = "animation5 2s ease 1 normal running 0s forwards";
  object2.addEventListener("animationend", function6);
}

function function6(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object5.style.animation = "animation6 2s ease 1 normal running 0s forwards";
  object5.addEventListener("animationend", function7);
}

function function7(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object8.style.animation = "animation7 2s ease 1 normal running 0s forwards";
  object8.addEventListener("animationend", function8);
}

function function8(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object5.style.animation = "animation8 2s ease 1 normal running 0s forwards";
  object5.addEventListener("animationend", function9);
}

function function9(e) {
  e.target.removeEventListener(e.type, arguments.callee);
  object4.style.animation = "animation9 2s ease 1 normal running 0s forwards";

}
#object1 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: blue;
  float: left;
}

#object2 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: green;
  float: left;
  animation-iteration-count: 2;
}

#object3 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: red;
  float: left;
}

#object4 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: purple;
  float: left;
}

#object5 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: orange;
  float: left;
}

#object6 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: brown;
  float: left;
}

#object7 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: pink;
  float: left;
}

#object8 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: tomato;
  float: left;
}

#object9 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: indigo;
  float: left;
}

#object10 {
  width: 50px;
  height: 50px;
  border-radius: 4px;
  background: mediumspringgreen;
  float: left;
}

#vacuum {
  height: 200px;
}

#vacuum2 {
  height: 1000px;
  width: 100px;
  float: left;
}

button {
  height: 50px;
  width: 65px;
  background-color: crimson;
  color: white;
  border-radius: 2px;
  margin-left: 60px;
}

@keyframes animation1 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  33% {
    transform: translateY(-70px) translateX(0px);
  }
  66% {
    transform: translateY(-70px) translateX(-200px);
  }
  100% {
    transform: translateY(-70px) translateX(-150px);
  }
}

@keyframes animation2 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  100% {
    transform: translateY(70px) translateX(0px);
  }
}

@keyframes animation3 {
  0% {
    transform: translateY(-70px) translateX(-150px);
  }
  100% {
    transform: translateY(-70px) translateX(250px);
  }
}

@keyframes animation4 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  33% {
    transform: translateY(70px) translateX(0px);
  }
  66% {
    transform: translateY(70px) translateX(-400px);
  }
  100% {
    transform: translateY(0px) translateX(-400px);
  }
}

@keyframes animation5 {
  0% {
    transform: translateY(70px) translateX(0px);
  }
  50% {
    transform: translateY(70px) translateX(400px);
  }
  100% {
    transform: translateY(0px) translateX(400px);
  }
}

@keyframes animation6 {
  0% {
    transform: translateY(-70px) translateX(250px);
  }
  50% {
    transform: translateY(-70px) translateX(200px);
  }
  100% {
    transform: translateY(-70px) translateX(150px);
  }
}

@keyframes animation7 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  100% {
    transform: translateY(70px) translateX(0px);
  }
}

@keyframes animation8 {
  0% {
    transform: translateY(-70px) translateX(-200px);
  }
  50% {
    transform: translateY(-70px) translateX(-150px);
  }
  100% {
    transform: translateY(-70px) translateX(-100px);
  }
}

@keyframes animation9 {
  0% {
    transform: translateY(0px) translateX(0px);
  }
  100% {
    transform: translateY(70px) translateX(0px);
  }
}

@keyframes animation10 {
  0% {
    transform: translateY(70px) translateX(0px);
  }
  50% {
    transform: translateY(70px) translateX(-250px);
  }
  100% {
    transform: translateY(0px) translateX(-250px);
  }
}

@keyframes animation11 {
  0% {
    transform: translateY(70px) translateX(0px);
  }
  50% {
    transform: translateY(70px) translateX(250px);
  }
  100% {
    transform: translateY(0px) translateX(250px);
  }
}
<div id="vacuum"></div>
<div id="vacuum2"></div>
<div id="object1"></div>
<div id="object2"></div>
<div id="object3"></div>
<div id="object4"></div>
<div id="object5"></div>
<div id="object6"></div>
<div id="object7"></div>
<div id="object8"></div>
<div id="object9"></div>
<div id="object10"></div>
<button onclick="function1()">Click Mom :)</button>

0

solved Multiple animations for 1 element JS, CSS [closed]