rcbyr / keen-slider

The HTML touch slider carousel with the most native feeling you will get.
https://keen-slider.io/
MIT License
4.67k stars 214 forks source link

Lazy loading when slides.perView > 1 #403

Open Raf-sns opened 8 months ago

Raf-sns commented 8 months ago

Hi ! Thanks for kee-slider which is a very nice program.

I encounter a problem: I tried to implement lazy loading with 3 images per view (but this is determined by breakpoints).

I have a default slides.perView value of 3.

I followed the example but I encountered a problem: The first image loads at startup, but not the next two which should be the first 3 visible images of the slider.

I have autoscroll and when it does, only the first image in the group of 3 images loads lazily.

Do you have any advice on this?

Sincerely, Raf

Here my function who launch keen-slider :

/**
 * $.launch_slider();
 *
 * @return {void}  init Keen-Slider
 */
launch_slider: function(Template) {

    // re-init Slider
    if (Slider != null) {

        Slider.destroy();
        Slider = null;
    }

    // not activate slider if not present
    if ($('#keen-slider').length == 0) {
        return;
    }

    // easing functions for `defaultAnimation`
    const easeOutCubic = (x) => {
        return 1 - Math.pow(1 - x, 3);
    }
    // or
    const easeOutSine = (x) => {
        return Math.sin((x * Math.PI) / 2);
    }

    // keen-slider container #id
    let Keen_Container = '#keen-slider';

    let Spacing = 0;

    // animation duration
    let AnimationDuration = 1000;

    // delay to slide next image
    let DelayToSlide = 5000;

    // lazy loading
    let Folder_imgs;
    let Nb_imgs;
    let Slider_imgs = [];
    let Slider_slides;
    let Container = document.getElementById('keen-slider');

    switch (Template) {
        case 'gite':
            Folder_imgs = 'GITE';
            Nb_imgs = 16;
            break;
        case 'home':
            Folder_imgs = 'SITE';
            Nb_imgs = 8;
            break;
    }

    for (var i = 1; i <= Nb_imgs; i++) {
        // push list of urls
        Slider_imgs.push(`IMGS/` + Folder_imgs + `/` + i + `.webp`);
        // create slides div
        Slider_slides = document.createElement('div');
        Slider_slides.classList.add('keen-slider__slide', 'lazy__slide');
        let img = document.createElement('img');
        // append imgs to slide
        Slider_slides.append(img);
        // append slide to container
        Container.append(Slider_slides);
    }

    let loaded = [];

    function loadImages(s) {

        const slideIdx = s.track.details.rel;

        loaded[slideIdx] = true;

        s.slides.forEach((element, idx) => {

            if (loaded[idx])
                element.querySelector("img").setAttribute("src", Slider_imgs[idx])
        });
    }
    // end lazy loading

    // KEEN-SLIDER
    Slider = new KeenSlider(Keen_Container, {
            animationEnded: loadImages,
            created: loadImages,
            mode: 'free-snap',
            // renderMode: 'performance',
            defaultAnimation: {
                duration: AnimationDuration,
                easing: easeOutSine,
            },
            loop: true,
            slides: {
                perView: 3,
                spacing: Spacing,
            },
            breakpoints: {
                '(min-width: 1500px)': {
                    slides: {
                        perView: 4,
                        spacing: Spacing,
                    },
                },
                '(max-width: 800px)': {
                    slides: {
                        perView: 2,
                        spacing: Spacing,
                    },
                },
                '(max-width: 600px)': {
                    slides: {
                        perView: 1,
                        spacing: Spacing,
                    },
                },
            },
        },
        [
            (slider) => {
                let timeout;
                let mouseOver = false;

                function clearNextTimeout() {

                    clearTimeout(timeout);
                }

                function nextTimeout() {

                    clearTimeout(timeout);

                    if (mouseOver) return;

                    timeout = setTimeout(() => {

                        slider.next();

                    }, DelayToSlide);
                }
                slider.on('created', () => {

                    slider.container.addEventListener('mouseenter', () => {
                        mouseOver = true
                        clearNextTimeout()
                    });

                    // slider.container.addEventListener('mouseout', () => {
                    //     mouseOver = false;
                    //     nextTimeout();
                    // });

                    nextTimeout();
                });

                slider.on('dragStarted', clearNextTimeout);
                slider.on('dragEnded', function() {
                    mouseOver = false;
                    nextTimeout
                });
                slider.on('animationEnded', nextTimeout);
                slider.on('updated', nextTimeout);
            }
        ]
    );

},
/**
 * $.launch_slider();
 */