And their animation times are randomized. Because I want each of them to have different durations, I ended up writing a monster script:
var purple = document.getElementById("purple");
var pink = document.getElementById("pink");
var green = document.getElementById("green");
var red = document.getElementById("red");
var darkgreen = document.getElementById("darkgreen");
function blinkpurple() {
var dur = Math.random() * 2.5 + 1;
purple.style.animationDuration = `${dur}s`;
}
function blinkpink() {
var dur = Math.random() * 2.5 + 3;
pink.style.animationDuration = `${dur}s`;
}
function blinkgreen() {
var dur = Math.random() * 2.5 + 3;
green.style.animationDuration = `${dur}s`;
}
function blinkred() {
var dur = Math.random() * 2.5 + 3;
red.style.animationDuration = `${dur}s`;
}
function blinkdarkgreen() {
var dur = Math.random() * 2.5 + 3;
darkgreen.style.animationDuration = `${dur}s`;
}
purple.addEventListener("animationiteration", blinkpurple);
pink.addEventListener("animationiteration", blinkpink);
green.addEventListener("animationiteration", blinkgreen);
red.addEventListener("animationiteration", blinkred);
darkgreen.addEventListener("animationiteration", blinkdarkgreen);
Is there any way to perhaps iterate over the elems (maybe add a class attr like class="neon darkgreen" and change all their animation-durations with only one function?
To get multiple elements from the page, look up document.querySelectorAll or document.getElementsByClassName. These let you get more than one element at a time the way getElementById does. The result is kind of like an array, but check what the return type is in their documentation if you want to learn about the subtle differences. See if you can code something up that uses this instead of multiple getElementByIds.
To perform kind of the same thing multiple times, such as doing the same thing to each element in a list of DOM nodes, look into using loops. A for loop could be suitable here, which gives you a variable that you can use inside the loop body to refer to a different value on each iteration, such as the iteration number or a different element from the list. See if you can write a loop to do something simple to each element that you get from the previous step.
Creating a callback function in a loop can be tricky because you might be closing over a loop variable that gets reassigned on each iteration. Use let instead of var to create separate variables for each iteration.
I’m not sure if this is consistent with the code you posted. Is it about looping through elements and giving each one a random duration, and then each one continuing to animate with that duration going forward? The code was something else, which looks like it would set a new random duration for each iteration of the animation, for each element.
It’s a way to do it, to have a variable that you can use inside the animationiteration callback that refers to the element that’s had an animation iteration end. You’re right to ask though; there is another way to get that. When the browser calls your event listener, it passes an event argument. Look up the Event class’s target attribute for information on this.
Ah yeah, I just realized - I could very easily randomize the durations once with a loop, but to keep doing it on animationend I would need callbacks. Having animationend in a loop would be the true obstacle.
var arr = document.getElementsByClassName("neon")
function test(event) {
console.log(event.target)
event.target.innerText = Math.round(Math.random() * 10)
}
for (var i = 0; i < arr.length; i++) {
var el = arr[i]
arr[i].addEventListener("animationiteration", test)
}