I’m trying to make a carousel but I found the problem that every time I switch tabs and return, the animations are delayed, is there a way to solve this?
Try to do something with the Page Visibility API but you can’t fix it.
My code:
"use strict";
class Carousel {
constructor(_options) {
this.images = [];
this.imgIndex = 1;
this.transitionStatus = null;
this.options = {
autoplay: {
enabled: true,
speed: 5000
},
speed: 5000
};
this.nextQueue = 0;
//config options
Object.assign(this.options, _options);
//set props
this.container = document.getElementsByClassName("carousel__container")[0];
this.itemsContainer = document.getElementsByClassName("carousel__items")[0];
//get imgs from carousel items and remove #text's childs
document.querySelectorAll(".carousel__item").forEach(item => {
item.childNodes.forEach((child) => child.nodeName === "IMG" ? this.images.push(child) : false);
});
this.setup();
}
setup() {
//add class to all images in carouselContainer
for (let index = 0; index < this.images.length; index++) {
const image = this.images[index];
image === null || image === void 0 ? void 0 : image.classList.add('carousel__itemImg'); /* img */
}
const toContainerFragment = document.createDocumentFragment();
// create span index image counter
this.spanIndex = document.createElement('span');
this.spanIndex.classList.add('container__number'); //imgIndex
this.updateIndexContent();
toContainerFragment.appendChild(this.spanIndex);
//create next prev arrows
const arrowNext = document.createElement("span");
arrowNext.id = "carousel_next";
arrowNext.textContent = "=>";
toContainerFragment.appendChild(arrowNext);
const arrowPrev = document.createElement("span");
arrowPrev.id = "carousel_prev";
arrowPrev.textContent = "<=";
toContainerFragment.appendChild(arrowPrev);
arrowNext.addEventListener("click", () => this.next());
arrowPrev.addEventListener("click", () => this.prev());
//add arrows and span index to container
this.container.appendChild(toContainerFragment);
//autoplay
if (this.options.autoplay.enabled) {
this.autoPlay();
}
}
next() {
if (this.imgIndex == this.images.length) {
this.imgIndex = 0;
}
if (this.transitionStatus == "started") {
this.nextQueue++;
return;
}
const clientWidth = this.container.clientWidth;
this.imgIndex++;
this.updateIndexContent();
this.itemsContainer.style.transition = `transform ${this.options.speed}ms linear`;
this.itemsContainer.style.transform = `translateX(-${clientWidth}px)`;
this.transitionStatus = "started";
const transitionEndEvent = () => {
this.itemsContainer.removeEventListener("transitionend", transitionEndEvent);
this.itemsContainer.style.transition = "";
this.itemsContainer.style.transform = `translateX(-{$content}px)`;
const previousElement = document.querySelectorAll(".carousel__item")[0];
this.itemsContainer.insertAdjacentElement("beforeend", previousElement);
this.transitionStatus = "ended";
if (this.nextQueue) {
this.nextQueue--;
this.next();
}
};
this.itemsContainer.addEventListener("transitionend", transitionEndEvent);
let currentTranslateX;
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
const computedStyle = window.getComputedStyle(this.itemsContainer);
var matrix = new WebKitCSSMatrix(computedStyle.transform);
currentTranslateX = matrix.m41;
}
else {
console.log(clientWidth);
console.log(currentTranslateX);
const resume = clientWidth + currentTranslateX;
console.log(resume);
}
});
}
updateIndexContent() {
this.spanIndex.textContent = `${this.imgIndex} / ${this.images.length}`;
}
autoPlay() {
setInterval(() => {
this.next();
}, this.options.autoplay.speed);
}
}
const carousel = new Carousel({
autoplay: {
enabled: false,
speed: 1000
},
speed: 5000
});
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Document</title>
</head>
<body>
<div class="carousel__container">
<div class="carousel__items">
<div class="carousel__item">
<img src="../assets/1.jpg" alt="" />
</div>
<div class="carousel__item">
<img src="../assets/2.jpg" alt="" />
</div>
<div class="carousel__item">
<img src="../assets/3.jpg" alt="" />
</div>
</div>
</div>
<script src="./main.js"></script>
</body>
</html>
IGNORE: It looks like your post is mostly code; please add some more details.
It looks like your post is mostly code; please add some more details.
Source: Ask Javascript Questions