Search code examples
javascriptjqueryhtmlbuttonslider

How do I let multiple sliders on one page function separate from each other?


You guys have been such a good help in the past. I hope you can help me out again! I'm still learning a lot, but I've just came across an issue I'm not able to fix myself. I've read similar posts with similar issues, but I wasn't able to implement those solutions...

I'm making an template for a client. In this template there is a slider, which works great.

Problem is: the client can add another slider to the same page. At that point the second slider doesn't 'work' when you click the arrows. Only the arrows of the first slider are working and also slides the second slider slides.

So, I think I understand that I should 'target' the specific ID or Class of every slider in my sliders code. Something with .find(), but I just can't get it to work.

Specific question: how do I make this code work, so that my customer can add as many sliders as he wants on 1 page, without the sliders effecting each others functionality.

I hope you can help me out.

Slider code:

    $(document).ready(function(){
    // options
    var speed = 500; //transition speed - fade
    var autoswitch = false; //auto slider options
    var autoswitch_speed = 5000; //auto slider speed
    
    // add first initial active class
    $(".slide").first().addClass("active");
    
    // hide all slides
    $(".slide").hide;
    
    // show only active class slide
    $(".active").show();
    

  
  
    // Next Event Handler
    $('.nextbtn').on('click', nextSlide);// call function nextSlide
    
    // Prev Event Handler
    $('.prevbtn').on('click', prevSlide);// call function prevSlide
    
    // Auto Slider Handler
    if(autoswitch == true){
        setInterval(nextSlide,autoswitch_speed);// call function and value 4000
    }
    
    // Switch to next slide
    function nextSlide(){
        $('.active').removeClass('active').addClass('oldActive');
        if($('.oldActive').is(':last-child')){
            $('.slide').first().addClass('active');
        } else {
            $('.oldActive').next().addClass('active');
        }
        $('.oldActive').removeClass('oldActive');
        $('.slide').fadeOut(speed);
        $('.active').fadeIn(speed);
    }
    
    // Switch to prev slide
    function prevSlide(){
        $('.active').removeClass('active').addClass('oldActive');
        if($('.oldActive').is(':first-child')){
            $('.slide').last().addClass('active');
        } else {
            $('.oldActive').prev().addClass('active');
        }
        $('.oldActive').removeClass('oldActive');
        $('.slide').fadeOut(speed);
        $('.active').fadeIn(speed);
    }
});

HTML Markup:

<div class="afbeeldingen-slider-container">  
<div class="container">
    
  
  <div id="container-slider" class="sliderbtn">
    
    <div id="prev" alt="Prev" title="Prev" class="nextbtn">             
                <i class="material-icons">keyboard_backspace</i>
            </div>
    
    <div id="next" alt="Next" title="Next" class="prevbtn"> 
                <i class="material-icons">keyboard_backspace</i>
            </div>          
    
    
    <div id="slider">
      
        {% for afbeelding_voor_slider in afbeelding_slider.afbeeldingen_toevoegen %}
          {% include afbeelding_voor_slider %}
        {% endfor %}
    </div>  
<div style="clear: both;"></div> 


  
</div>  
</div>
</div>

Solution

  • Since you have multiple sliders on your page with the same classes, jQuery picks the last one to work on, because the code is parsed and interpreted from top to bottom.

    What would be best in your case is to make a global slider function, and use it on the sliders. Something like:

    $(".slider").initSlider();
    

    Inside the function you would find all specific DOM elements relative to the slider:

    var nextbtn = $(this).find(".nextbtn")
    

    This way the code runs for every slider, instead of the last one. But this is a very rudimentary example. Actually I'd recommend using an existing library where this functionality is already built in and tested. Take a look at http://jquery.malsup.com/cycle2/ which is a very basic slider library, but you can extend it however you like.

    I see you're using the Plate cms. ;) Plate has Cycle2 built in in it's global_asset_url filter: https://platehub.github.io/docs/templating-reference/filters#global_asset_url