Why when I switch tabs, the transitions are delayed, is there any way to fix it?

  javascript

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.

Image from Gyazo

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

LEAVE A COMMENT