I've built a little carousel programme in vanilla JavaScript and it's working great, except when I visit another browser window and then come back to my carousel window.
The slides race past each other, as though they've been waiting to run while I've been elsewhere, until it reaches the slide it would have been at had I been watching the whole time, which often slides in from the wrong side. Then it settles down and continues to work as expected. This behaviour is the same in Chrome and Firefox.
The full code is on GitHub at https://github.com/lucywho/lightweight-carousel but this is the relevant section of the script:
const slide = document.querySelectorAll("#carousel .carousel-slide");
const dots = document.querySelectorAll("#dots .dot");
const total = slide.length;
let last = total - 1;
let i = 0;
let timer;
let isTransitioning = false;
timer = setTimeout(moveSlide, 5000);
function moveSlide(index) {
isTransitioning = true;
if (typeof index == "number") {
if (i === index) {
return;
} else {
slide[i].classList.remove("onscreen");
dots[i].classList.remove("fill-in");
slide[i].classList.add("offscreen-left");
i = index;
dots[i].classList.add("fill-in");
slide[i].classList.add("onscreen");
}
} else if (i < last) {
slide[i].classList.remove("onscreen");
dots[i].classList.remove("fill-in");
slide[i].classList.add("offscreen-left");
i++;
dots[i].classList.add("fill-in");
slide[i].classList.add("onscreen");
} else if (i === last) {
slide[i].classList.remove("onscreen");
dots[i].classList.remove("fill-in");
slide[i].classList.add("offscreen-left");
i = 0;
dots[i].classList.add("fill-in");
slide[i].classList.add("onscreen");
}
timer = setTimeout(moveSlide, 7000);
}
document.addEventListener("transitionend", function(event) {
if (event.target.classList.contains("offscreen-left")) {
event.target.classList.remove("offscreen-left");
isTransitioning = false;
}
Am I right in thinking that the problem is something to do with the script continuing to run in the background even when the page is not displayed? And if so, how do I force JavaScript to pause? (I tried wrapping it all in a document.addEventListener("DOMContentLoaded", function(){}
but that didn't help)
Many thanks in advance.
ETA: thanks to Andre, I've tried the following approach. Again, it runs happily when the page loads but I'm still getting a few seconds of weirdness when I return from another tab.
let screenVis = true;
if (screenVis) {
...
carousel code
...
}
document.addEventListener("visibilitychange", function() {
if (document.hidden === true) {
screenVis = false;
} else {
screenVis = true;
}
});
So, either I've mucked up my code (always possible) or something else is going on?