Autoplay-Karussell

Für dieses Karussell wird CSS-Scroll-Snap verwendet, um reibungslose, leistungsstarke Folienübergänge zu erzeugen, die keine Layoutverschiebungen verursachen.

Es gibt verschiedene Möglichkeiten, in diesem Karussell zu navigieren: Zusätzlich zu den Navigationsbedienelementen unterstützt es die Tastaturnavigation und das Wischen. Zur Maximierung der Nutzerfreundlichkeit und Lesbarkeit stoppt das Karussell den automatischen Wechsel, sobald der Nutzer den Mauszeiger im Karussellbereich bewegt.

HTML

<div id="carousel">
  <div id="slide-container">
    <div class="slide" data-slideIndex="0">
      <div class="slide-banner">Tour the Empire State Building! <a href="">Buy tickets now.</a></div>
      <img width="1200" height="600" src="./newyork.jpg">
    </div>
    <div class="slide" data-slideIndex="1">
      <div class="slide-banner">Ride the Shinkansen! <a href="">Buy tickets now.</a></div>
      <img width="1200" height="600" src="./tokyo.jpg">
    </div>
    <div class="slide" data-slideIndex="2">
      <div class="slide-banner">Discover relaxation! <a href="">Buy tickets now.</a></div>
      <img width="1200" height="600" src="./beach.jpg">
    </div>
    <div class="slide" data-slideIndex="3">
      <div class="slide-banner">See penguins! <a href="">Buy tickets now.</a></div>
      <img width="1200" height="600" src="./penguins.jpg">
    </div>
    <div class="slide" data-slideIndex="4">
      <div class="slide-banner">Take a ride on the wheel! <a href="">Buy tickets now.</a></div>
      <img width="1200" height="600" src="./wheel.jpg">
    </div>
  </div>
  <div id="back-button" class="arrow back">←</div>
  <div id="forward-button" class="arrow forward">→</div>
  <div class="slide-indicators">
    <div class="slide-indicator active"></div>
    <div class="slide-indicator"></div>
    <div class="slide-indicator"></div>
    <div class="slide-indicator"></div>
    <div class="slide-indicator"></div>
  </div>
</div>

CSS


        #carousel {
    max-width: 1200px;
    display: flex;
    flex-direction: column;
    margin: 0 auto;
    position: relative;
}  
.slide-indicators {
    display: flex;
    justify-content: center;
}
.slide-indicator {
    height: 44px;
    width: 50px;
    display: flex;
    justify-items: center;
    cursor: pointer;
}
.slide-indicator:after {
    content: "";
    background-color: #878787;
    height: 10px;
    margin-top: 10px;
    width: 40px;
}
.slide-indicator.active:after,
.slide-indicator:hover:after {
    background-color: #000;
}
.slide-banner {
    background-color: #000;
    color: #fff;
    position: absolute;
    left: 0;
    bottom: 20px;
    padding: 15px;
    font-size: 2.5vw;
}
.slide-banner a {
    color: #fff;
}
#slide-container {
    scroll-snap-type: x mandatory;
    overflow-x: scroll;
    overflow-y: hidden;
    display: flex;
    align-items: center;
    height: 100%;
    gap: 10px;
    -webkit-overflow-scrolling: touch;
    scroll-behavior: smooth;
}
.slide {
    scroll-snap-align: center;
    position: relative;
    min-width: 100%;
    padding-top: 50%;
}
.slide img {
    height: 100%;
    width: auto;
    position: absolute;
    top: 0;
    left: 0;
}
.arrow {
    color: #fff;
    height: 20px;
    width: 20px;
    background-color: #000;
    position: absolute;
    padding: 10px;
    opacity: .3;
    cursor: pointer;
}
.arrow.back {
    left: 10px;
    top: 10px;
}
.arrow.forward {
    right: 10px;
    top: 10px;
}
.arrow:hover {
    opacity: 1;
}
        

JS


        function autoplayCarousel() {
    const carouselEl = document.getElementById("carousel");
    const slideContainerEl = carouselEl.querySelector("#slide-container");
    const slideEl = carouselEl.querySelector(".slide");
    let slideWidth = slideEl.offsetWidth;
    // Add click handlers
    document.querySelector("#back-button")
        .addEventListener("click", () => navigate("backward"));
    document.querySelector("#forward-button")
        .addEventListener("click", () => navigate("forward"));
    document.querySelectorAll(".slide-indicator")
        .forEach((dot, index) => {
            dot.addEventListener("click", () => navigate(index));
            dot.addEventListener("mouseenter", () => clearInterval(autoplay));
        });
    // Add keyboard handlers
    document.addEventListener('keydown', (e) => {
        if (e.code === 'ArrowLeft') {
            clearInterval(autoplay);
            navigate("backward");
        } else if (e.code === 'ArrowRight') {
            clearInterval(autoplay);
            navigate("forward");
        }
    });
    // Add resize handler
    window.addEventListener('resize', () => {
        slideWidth = slideEl.offsetWidth;
    });
    // Autoplay
    const autoplay = setInterval(() => navigate("forward"), 3000);
    slideContainerEl.addEventListener("mouseenter", () => clearInterval(autoplay));
    // Slide transition
    const getNewScrollPosition = (arg) => {
        const gap = 10;
        const maxScrollLeft = slideContainerEl.scrollWidth - slideWidth;
        if (arg === "forward") {
            const x = slideContainerEl.scrollLeft + slideWidth + gap;
            return x <= maxScrollLeft ? x : 0;
        } else if (arg === "backward") {
            const x = slideContainerEl.scrollLeft - slideWidth - gap;
            return x >= 0 ? x : maxScrollLeft;
        } else if (typeof arg === "number") {
            const x = arg * (slideWidth + gap);
            return x;
        }
    }
    const navigate = (arg) => {
        slideContainerEl.scrollLeft = getNewScrollPosition(arg);
    }
    // Slide indicators
    const slideObserver = new IntersectionObserver((entries, observer) => {
        entries.forEach(entry => {
            if (entry.isIntersecting) {
                const slideIndex = entry.target.dataset.slideindex;
                carouselEl.querySelector('.slide-indicator.active').classList.remove('active');
                carouselEl.querySelectorAll('.slide-indicator')[slideIndex].classList.add('active');
            }
        });
    }, { root: slideContainerEl, threshold: .1 });
    document.querySelectorAll('.slide').forEach((slide) => {
        slideObserver.observe(slide);
    });
}
autoplayCarousel();