javascriptpaginationslideshowautoplay

Combine features in JS Slideshow


So, I found a simple slideshow here: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow

Then, I saw how this could be automated: https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_slideshow_auto

The only thing is, they remove the arrows...I would like to keep the arrows so people can go back or forward if they want to. My code is the same as theirs, but it looks like:

The HTML:

<div class="slideshow-container">

<div class="mySlides fade">
    <div class="numbertext">1 / 3</div>
    <img src="img_nature_wide.jpg" style="width:100%">
    <div class="text">Caption Text</div>
</div>

<div class="mySlides fade">
    <div class="numbertext">2 / 3</div>
    <img src="img_snow_wide.jpg" style="width:100%">
    <div class="text">Caption Two</div>
</div>

<div class="mySlides fade">
    <div class="numbertext">3 / 3</div>
    <img src="img_mountains_wide.jpg" style="width:100%">
    <div class="text">Caption Three</div>
</div>

<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>

</div>

<br>

<div style="text-align:center">
    <span class="dot" onclick="currentSlide(1)"></span> 
    <span class="dot" onclick="currentSlide(2)"></span> 
    <span class="dot" onclick="currentSlide(3)"></span> 
</div>

The JS:

let slideIndex = 1;
showSlides(slideIndex);

function plusSlides(n) {
    showSlides(slideIndex += n);
}

function currentSlide(n) {
    showSlides(slideIndex = n);
}

function showSlides(n) {
    let i;
    let slides = document.getElementsByClassName("mySlides");
    let dots = document.getElementsByClassName("dot");
    if (n > slides.length) {slideIndex = 1}    
    if (n < 1) {slideIndex = slides.length}
    for (i = 0; i < slides.length; i++) {
        slides[i].style.display = "none";  
    }
    for (i = 0; i < dots.length; i++) {
        dots[i].className = dots[i].className.replace(" active", "");
    }
    slides[slideIndex-1].style.display = "block";  
    dots[slideIndex-1].className += " active";
}

I tried to add the autoplay to my JS, by adjusting the last little bit of JS:

slides[slideIndex-1].style.display = "block";  
dots[slideIndex-1].className += " active";
setTimeout(showSlides, 2000); // Change image every 2 seconds

But that doesn't seem to do anything, I'm thinking it's because the there are some minor differences between the two scripts.

Could someone help me tweak this so the autoplay works, but the prev/next arrows and pagination at the bottom still work?

Thanks,
Josh


Solution

  • I spent some more time researching, I was actually trying to scrap what I had for something else, then I ran across: Automatic Slideshow with Arrows and Buttons

    To my surprise, it's the same code I was already using! So, basically, I just had to swap out my JS for this one and everything started working!

    The JS now looks like:

    var slideIndex = 0;
    showSlides();
    //add the global timer variable
    var slides,dots,timer;
    
    function showSlides() {
        var i;
        slides = document.getElementsByClassName("mySlides");
        dots = document.getElementsByClassName("dot");
        for (i = 0; i < slides.length; i++) {
           slides[i].style.display = "none";  
        }
        slideIndex++;
        if (slideIndex> slides.length) {slideIndex = 1}    
        for (i = 0; i < dots.length; i++) {
            dots[i].className = dots[i].className.replace(" active", "");
        }
        slides[slideIndex-1].style.display = "block";  
        dots[slideIndex-1].className += " active";
        //put the timeout in the timer variable
        timer = setTimeout(showSlides, 4000); // Change image every 8 seconds
    }
    
    function plusSlides(position) {
        //clear/stop the timer
        clearTimeout(timer);
        slideIndex +=position;
        if (slideIndex> slides.length) {slideIndex = 1}
        else if(slideIndex<1){slideIndex = slides.length}
        for (i = 0; i < slides.length; i++) {
           slides[i].style.display = "none";  
        }
        for (i = 0; i < dots.length; i++) {
            dots[i].className = dots[i].className.replace(" active", "");
        }
        slides[slideIndex-1].style.display = "block";  
        dots[slideIndex-1].className += " active";
        //create a new timer
        timer = setTimeout(showSlides, 4000);
    }
    
    function currentSlide(index) {
        //clear/stop the timer
        clearTimeout(timer);
        if (index> slides.length) {index = 1}
        else if(index<1){index = slides.length}
        //set the slideIndex with the index of the function
        slideIndex = index;
        for (i = 0; i < slides.length; i++) {
           slides[i].style.display = "none";  
        }
        for (i = 0; i < dots.length; i++) {
            dots[i].className = dots[i].className.replace(" active", "");
        }
        slides[index-1].style.display = "block";  
        dots[index-1].className += " active";
        //create a new timer
        timer = setTimeout(showSlides, 4000);
    }
    

    I even like the small tweak they made to the seconds, changing the timer from 2 seconds to 8 seconds :-)

    Hope this helps someone else!

    Thanks @Below the Radar