Ghoyos Ghoyos - 3 months ago 5
Javascript Question

Want to understand why this works in JavaScript?

Yesterday I asked a question (original question) that was promptly answered, but even though a solution was found, I don't understand why this is working the way it is. I can duplicate this solution for other things I need to do but before I continue on I would like to understand why this works the way it does.

So basically I made three functions that called each other. The 1st called the second upon "animationend" and the second called the third upon an "animationend" and the finally the third function called the first to start the cycle all over again - BUT My original code though lacked;

document.getElementById("rightBoxTwo").style.animation = "none";


which was needed in-order for the third function to call the first so the cycle starts all over again. Without the above code in each function the three functions would work only once and then stop. The answer that StackOverFlow user; ScientiaEtVeritas gave me included a CodePen which had a working example of what I needed and a brief explanation


So, I think you have several options: What could work is that you
reset the the animation of
rightBox
in function
runTwo
with
animation: none
. If you assign
scrollTextTwo 10s
back to the
rightBox
it should start again. Equivalent for the other ones.


So finally my question is WHY does the animation need to be cleared, and why does the
.style.animation = "none";
accomplish this?

below is the working code after a solution was presented...

<body onload="runOne()">


function runOne() {
var x = document.getElementById("rightBox");
x.addEventListener("animationend",runTwo);
document.getElementById("rightBox").style.animation = "scrollTextTwo 10s";
document.getElementById("rightBoxTwo").style.animation = "none";
}
function runTwo() {
var x = document.getElementById("rightBoxTwo");
x.addEventListener("animationend",runThree);
document.getElementById("rightBoxTwo").style.animation =
"scrollTextTwo 10s";
document.getElementById("rightBoxThree").style.animation = "none";
}
function runThree() {
var x = document.getElementById("rightBoxThree");
x.addEventListener("animationend",runOne);
document.getElementById("rightBoxThree").style.animation =
"scrollTextTwo 10s";
document.getElementById("rightBox").style.animation = "none";
}

Answer

The simplest reason is because setting the animation to the same thing twice (or more times) is the same as doing it once:

let box = document.getElementById('box');

// animation happens once
for (let i = 0; i < 5; i++) {
  box.style.animation = 'fade .5s';
}
@keyframes fade {
  from {
    opacity: 1
  }
  to {
    opacity: 0
  }
}
#box {
  height: 200px;
  width: 200px;
  margin: 50px;
  background: #018bbc;
}
<div id="box"></div>

The behavior is the same even if you delay the animation so each time it runs after a possible render:

let box = document.getElementById('box');

// animation still happens once
for (let i = 0; i < 5; i++) {
  setTimeout(function() {
    box.style.animation = 'fade .5s';
  }, i * 1000);
}
@keyframes fade {
  from {
    opacity: 1
  }
  to {
    opacity: 0
  }
}
#box {
  height: 200px;
  width: 200px;
  margin: 50px;
  background: #018bbc;
}
<div id="box"></div>

But if I reset the animation before each step, the engine has to re-set the animation, which in a way means to "install the animation again", meaning it will be animated again:

let box = document.getElementById('box');

box.addEventListener('animationend', function() {
  box.style.animation = 'none';
});

// animation now happens every time
for (let i = 0; i < 5; i++) {
  setTimeout(function() {
    box.style.animation = 'fade .5s';
  }, i * 1000);
}
@keyframes fade {
  from {
    opacity: 1
  }
  to {
    opacity: 0
  }
}
#box {
  height: 200px;
  width: 200px;
  margin: 50px;
  background: #018bbc;
}
<div id="box"></div>

Comments