The Issue
The issue is caused by multiple eventListener’s being attached to the same object. Specifically:
function2starts an animation onobject2and attaches ananimationendlistener toobject2function5starts an animation onobject2and attaches ananimationendlistener toobject2(the 2nd event listener onobject2)- when the animation in
function5()completes the event listeners fromfunction2andfunction5are both called - the callback functions from the event listeners in
function2andfunction5cause newanimationendevents to trigger, causingfunction3andfunction6to 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]