Javascript: Trying to refactor so many IF statements in order to display pictures continuously

Viewed 37

I am trying to display a slideshow of images from an array using a promise. On load, I want the page to display the first image, then the next, and so on. When it's at the last picture index, I want the first picture to display and the code to keep repeating.

The class '.show-image' is visibility: visible. I have the first picture index classed as '.show-image', but the rest are hidden.

Is there a cleaner way of writing this without having so many IF statements?

let pictures= document.querySelectorAll(".moving-pics img");

async function changePicture() {
     
    for (let x=0; x < pictures.length; x++) {
           
       await new Promise(resolve => {
             setTimeout(() => {
                
                 if (!pictures[x - 1]) {
                     pictures[pictures.length - 1].classList.remove('show-image');
                 }

                 if (pictures[x - 1] && pictures[x - 1].classList.contains('show-image')) {
                     pictures[x - 1].classList.remove('show-image');

                 }
      
                 pictures[x].classList.add('show-image');
                 if (!pictures[x + 1]) {

                     resolve();
                     changePicture();
                    
                 }
                 resolve()
             }, 3000)
        });                  
    }
}

1 Answers

If you keep the index being iterated over in a persistent outer variable, you can use it to identify the last element with the show-image. Use optional chaining so the first iteration doesn't throw. To move on to the next image, use modulo to keep things concise.

I'd also just use setTimeout, if you have an individual call of changePicture change a single picture, I don't think there's any need for the Promise anymore:

let i = -1;
function changePicture() {
    pictures[i]?.classList.remove('show-image');
    i = (i + 1) % pictures.length;
    pictures[i].classList.add('show-image');
    setTimeout(changePicture, 3000);
}
Related