MansNotMike
MansNotMike

Reputation: 71

multiple Splide sliders

I'm using this site & Splide.js for the first time. I know some basics but i'm not experienced in this. I want to create multiple slides on my page but the mainslide stays active all the time.

So what I'm doing is creating both sliders:

document.addEventListener( 'DOMContentLoaded', function () {
    mainslide = new Splide( '#mainslide', {
        type   : 'loop',
        perPage: 5,
        perMove: 1,
        direction: 'rtl',
        trimSpace: false,
        keyboard: true,
        gap: '1em',
        width: '100%',
        height: '100%',
    })
    wheelslide = new Splide( '#wheelslide', {
        type: 'loop',
        perPage: 5,
        perMove: 1,
        direction: 'rtl',
        trimSpace: false,
        keyboard: true,
        gap: '1em',
        width: '100%',
        height: '100%'
    })
} );

When I'm opening my page im doing:

mainslide.mount();

And when i'm opening another page where I want to display another slider i'm doing:

$('#mainslide').hide()
mainslide.destroy(true)
mainslide.mount();
$('#wheelslide').show()

Whats happening now is that the new page or the new slider still thinks i'm working with the first slider. So the first slider does not get destroyed imo. When I console.log the id of the slider i still have the id mainslide01 instead it should be wheelslide01. I'm a bit stuck and I dont know how to continue from here.

Thanks in advance

Upvotes: 7

Views: 16810

Answers (2)

herrstrietzel
herrstrietzel

Reputation: 17317

When working with multiple slider instances I recommend using the inbuild 'data-splide' attribute for a slider specific setup.

  1. So you're writing your splide.js html markup as usual
  2. Add your slider options within the predefined "data-splide" attribute e.g:

<div class="splide" data-splide='{"type":"loop","perPage":3, "arrows":false, "pagination":false, "heightRatio":0.25 }'>
See official documentation: https://splidejs.com/guides/options/#by-data-attribute

  1. Now you can run a rather generic initializing/mounting function for all slider instances

var splides = document.querySelectorAll('.splide');
// 1. query slider elements: are there any splide elements?
if(splides.length){
    // 2. process all instances
    for(var i=0; i<splides.length; i++){
        var splideElement = splides[i];
        //3.1 if no options are defined by 'data-splide' attribute: take these default options
        var splideDefaultOptions = 
        {
            type   : 'slide',
            rewind: true,
            perPage: 1,
            autoplay:false,
            arrows:true,
            pagination:true,
            drag:true,
            keyboard:true,
            heightRatio: 0.5,
            cover: true,
        }
        /**
        * 3.2 if options are defined by 'data-splide' attribute: default options will we overridden
        * see documentation: https://splidejs.com/guides/options/#by-data-attribute
        **/
        
        var splide = new Splide( splideElement, splideDefaultOptions ); 
        // 3. mount/initialize this slider
        splide.mount();
    }
}
<link href="https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/css/splide.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/@splidejs/[email protected]/dist/js/splide.min.js"></script>


            <div class="splide">
              <div class="splide__track">
                <ul class="splide__list">
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/237/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/236/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/235/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/234/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/233/200/300" class="slider-img">
                  </li>
                </ul>
              </div>
            </div>
      
            <div class="splide" data-splide='{"type":"loop","perPage":3, "arrows":false, "pagination":false, "heightRatio":0.25 }'>
              <div class="splide__track">
                <ul class="splide__list">
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/237/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/236/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/235/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/234/200/300" class="slider-img">
                  </li>
                  <li class="splide__slide">
                    <img src="https://picsum.photos/id/233/200/300" class="slider-img">
                  </li>
                </ul>
              </div>
            </div>

Potential pitfalls: The data attribute is actually a JSON string containing object keys enclosed in double quotes. Make sure your data attribute is enclosed in single quotes like data-splide='...'

The main benefit:
you just need one general mounting function that could be stored in an external js file and loaded on any page (after splide.js) e.g:

<script src="..splide.min.js"></script>
<script src="..splide-init.js"></script>

You might also combine/concatenate your splide.js core file with the init script and load it deferred to minimize render blocking:

<script src="..splide.combined.js" defer></script>

Upvotes: 3

Alvand
Alvand

Reputation: 141

I had a problem too but I could resolve it. See the code below:

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="assets/css/splide-core.min.css">
  <script src="assets/js/splide.min.js"></script>
  <script>
    document.addEventListener('DOMContentLoaded', function () {
      new Splide('#new-product', {
        perPage: 3,
        perMove: 1,
        gap: "30px",
        pagination: false,
      }).mount();
    });
    
    document.addEventListener('DOMContentLoaded', function () {
      new Splide('#featured-product', {
        perPage: 4,
        perMove: 1,
        gap: "30px",
        pagination: false,
      }).mount();
    });
  </script>
  <title>SplideJS</title>
</head>
<body>

<div id="new-product" class="splide">
    <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide">Slide 01</li>
            <li class="splide__slide">Slide 02</li>
            <li class="splide__slide">Slide 03</li>
            <li class="splide__slide">Slide 04</li>
            <li class="splide__slide">Slide 05</li>
        </ul>
    </div>
</div>

<div id="featured-product" class="splide">
    <div class="splide__track">
        <ul class="splide__list">
            <li class="splide__slide">Slide 01</li>
            <li class="splide__slide">Slide 02</li>
            <li class="splide__slide">Slide 03</li>
            <li class="splide__slide">Slide 04</li>
            <li class="splide__slide">Slide 05</li>
            <li class="splide__slide">Slide 06</li>
      <li class="splide__slide">Slide 07</li>
        </ul>
    </div>
</div>

</body>
</html>

Just add an id attribute to main sliders containers and then refer to them in Splide initialization code. You will see two sliders work well separately on the same page.

Upvotes: 9

Related Questions