Creare uno slider di contenuti con scrolling infinito in JavaScript

Creare uno slider di contenuti con scrolling infinito in JavaScript

In questo articolo vedremo come creare uno slider di contenuti con scrolling infinito. Con JavaScript dobbiamo adottare una tecnica specifica.

Collegheremo i pulsanti di navigazione alle slide con un attributo di dati che conterrà l'indice numerico della slide corrente nel DOM.

Ogn volta che tale indice corrisponderà all'ultima slide dello slider, cloneremo le slide già presenti e le aggiungeremo al loro contenitore aggiornando al contempo l'indice delle slide nei pulsanti di navigazione.

Cominciamo impostando la struttura generale:

function setUpslider(container = null) {
        if(!container) {
            return;
        }
        const widthFactor = 12;
        const baseWidth = container.offsetWidth;
        const slides = container.querySelectorAll('li');
        for(const slide of slides) {
            slide.style.width = `${baseWidth}px`;
        }
        container.querySelector('.slider-wrapper').style.minWidth = `${baseWidth * widthFactor}px`;
        const sliderNav = document.createElement('nav');
        sliderNav.className = 'slider-nav';
        for(let i = 0; i < slides.length; i++) {
            let btn = document.createElement('button');
            btn.type = 'button';
            btn.dataset.slide = i;
            btn.innerHTML = `<span>${i+1}</span>`;
            sliderNav.appendChild(btn);
        }
        container.appendChild(sliderNav);
    }

La parte nascosta dello slider si estende in larghezza in modo da permettere alle slide di disporsi su un'unica riga. Al clic su ogni pulsante possiamo aggiungere un marcatore visivo:

function handleActiveButton(container, btn) {
        if(!container) {
            return;
        }
        const nav = container.querySelector('.slider-nav');
        if(!nav) {
            return;
        } 
        const buttons = nav.querySelectorAll('button');
        for(const button of buttons) {
            button.classList.remove('active');
        }
        btn.classList.add('active');

    }

Per creare lo scroll infinito definiamo una funzione che usa l'indice corrente delle slide per aggiornare lo slider qualora ci siano le condizioni necessarie, ossia che ci troviamo sull'ultima slide.

function handleInfiniteScroll(container, index) {
        if(!container) {
            return;
        }
        const slides = container.querySelectorAll('li');
        if((index + 1) === slides.length) {
            for(const slide of slides) {
                const copy = slide.cloneNode(true);
                copy.classList.add('cloned');
                slide.parentNode.appendChild(copy);
            }
            const cloned = container.querySelectorAll('.cloned');
            for(const clone of cloned) {
                clone.style.width = `${container.offsetWidth}px`;
            }
            const buttons = container.querySelectorAll('.slider-nav button');
            let start = parseInt(buttons[buttons.length - 1].dataset.slide, 10);
            for(const button of buttons) {
                start++;
                button.dataset.slide = start;
            }
        }
    }

La nuova indicizzazione partirà dall'indice dell'ultimo pulsante di navigazione. Quindi andiamo a gestire la navigazione delle slide:

function handleSliderNavigation(container = null) {
        if(!container) {
            return;
        }
        const nav = container.querySelector('.slider-nav');
        if(!nav) {
            return;
        }
        const buttons = nav.querySelectorAll('button');
        const wrapper = container.querySelector('.slider-wrapper');
        

        for(const button of buttons) {
            button.addEventListener('click', () => {
                const slides = wrapper.querySelectorAll('li');
                const idx = parseInt(button.dataset.slide, 10);
                const slide = slides[idx];
                if(slide) {
                    const left = slide.offsetLeft;
                    const rule = `translateX(-${left}px)`;
                    wrapper.style.transform = 'translateX(0)';
                    wrapper.style.transform = rule;
                    handleActiveButton(container, button);
                    handleInfiniteScroll(container, idx);
                    
                }
            });
        }
    }

Infine, inizializziamo il codice come segue:

document.addEventListener('DOMContentLoaded', () => {
        const slider = document.querySelector('.slider');
        setUpslider(slider);
        handleSliderNavigation(slider);
});

Demo

JavaScript Infinite Content Slider

Conclusione

Uno slider infinito non è altro che un contenitore i cui discendenti vengono clonati quando si è giunti sull'ultima slide della lista. Si tratta di una tecnica JavaScript non eccessivamente complessa da implementare.