ganlanyuan / tiny-slider

Vanilla javascript slider for all purposes.
MIT License
5.26k stars 785 forks source link

Nav showing more buttons than expected #583

Open bertuuk opened 4 years ago

bertuuk commented 4 years ago

Issue description:
Nav is showing more buttons than expected.

In this case, I have 4 elements and 3 are shown, sliding from 3 to 3. The controls work correctly, they only allow me to click once and I'm already at the end (3 + 1), but the nav shows 4 buttons, there are two buttons that have no functionality or meaning

The problem is on desktop, since on mobile it slides one by one

Demo link/slider setting:

const slider = Tns({
    container: '#slider-full-services',
    items: 1,
    slideBy: 1,
    mouseDrag: true,
    controls: false,
    nav: true,
    navPosition: 'bottom',
    gutter: 10,
    edgePadding: 0,
    autoWidth: true,
    lazyload: true,
    loop: false,
    responsive: {
        960: {
            items: 3,
            slideBy: 3,
            autoWidth: false,
            controls: true,
            controlsText: [ '<img src="/public/icons/arrow-left.svg">', '<img src="/public/icons/arrow-right.svg">' ],
        },
    },
})

Tiny-slider version: 2.9.2 Browser name && version: Lots of browsers and SO

zhgabor commented 4 years ago

ISSUE/FIX nav item generator, handler should duplicate/remove items as needed by responsive breakpoints

EXAMPLE i have 4 slides slideby "page" i will generate 2 dots, but on mobile i need 4

        var features = tns({
                container: '.feature-slides-holder',
                speed: 600,
                slideBy: 1,
                // center: true,
                mouseDrag: true,
                loop:false,
                controls: false,
                nav: true,
                // swipeAngle:false,
                // autoplay: true,
                gutter: 40,
                // controlsContainer: "#sliderControls",
                navContainer: "#sliderItems",
                items:1,
                responsive: {
                    "1200": {
                        items: 2,
                        slideBy:"page"
                        //edgePadding: 100,
                        //gutter: 50,
                        // fixedWidth: 650,
                    }
                },
            });
            <div id="sliderItems" class="slidercontrols mt-3 mt-md-5 ml-2 ml-md-0">
                <?php for($j=0;$j<floor($i/2);$j++):?>
                    <span class="d-inline-block text-light-gray item"><span class="icon icon-dot"></span></span>
                <?php endfor;?>
            </div>

then when on mobile tns expects 4 nav items and gives error also

Screenshot_4

HACK/FIX

generate all the dots for each slide then hide calculate paging and hide the unnecessary elements

                <?php for($j=0;$j<$i;$j++):
                    $css = "";
                    if($j>=floor($i/2)) $css = "d-xl-none";
                    ?>
                    <span class="d-inline-block text-light-gray item <?=$css;?>"><span class="icon icon-dot"></span></span>
                <?php endfor;?>

this way i will only show the correct paging nav items

hansfelix commented 4 years ago

I have the same issue

hansfelix commented 4 years ago

I did it in this way :

            let slider = tns({
                container: container,
                items: 1,
                mouseDrag: true,
                controls: false,
                navPosition: "bottom",
                freezable: false,
                rewind: true,
                autoplay: true,
                autoplayButtonOutput: false,
                navContainer: navContainer,
                gutter: 20,
                responsive: {
                    0: {
                        items: 1
                    },
                    768: {
                        items: 3
                    },
                    1200: {
                        items: 4
                    }
                }
            });

           const updateNav = function () {
                let pages = slider.getInfo().pages;
                Array.from(slider.getInfo().navContainer.children).forEach(function (item, index) {
                    item.style.display = 'block'
                    if(index >= pages) item.style.display = 'none'
                });
           }

           updateNav();

            slider.events.on('newBreakpointStart', updateNav);

In my case I create custom navContainer because I need to apply custom css classes, finally I decided to chande the code above to:

        // Css class for nav
        slider.getInfo().navContainer.classList.add('slider-pages');
        Array.from(slider.getInfo().navContainer.children).forEach(function (item, index) {
            item.classList.add('slider-dot')
        });