Review Carousel Problem

Hi all :slight_smile:

I am currently trying to build a review carousel that essentially displays one photo at a time, but will rotate the displayed photo upon clicking either the left or right button. I have managed to get to the point of trying to add some JS that will add ‘hidden’ or ‘visible’ to the classList of the specified element, but I cannot get it to work and it is no longer throwing any errors in Dev Tools. Any advice would be greatly appreciated.

JS:

let slidePosition = 0;
const slides = document.getElementsByClassName('carousel-item');
let totalSlides = slides.length;

function nextReview() {
    if (slidePosition == totalSlides - 1) {
        slidePosition = 0; 
    } else {
        slidePosition++;
    }

    updateSlidePosition();
}

function previousReview() {
    if (slidePosition == 0) {
        slidePosition = 0;
    } else {
        slidePosition--;
    }
    
    updateSlidePosition();
}

function updateSlidePosition() {
    for (let slide of slides) {
        slide.classList.remove('visible');
        slide.classList.add('hidden');
    }

    slides[slidePosition].classList.add('visible');
}

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" type="text/css" href="styles.css">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">    
    <title>Review Page</title>
</head>
<body>
    <div class="heading">
        <h1>Our Reviews:</h1>
        <hr>
    </div>
            <div class="name">
                <h2>John Doe</h2>
            </div>
                <div class="carousel">
                    <div class="carousel-item" style="display: block">
                        <img id="defVisible" src="./Images/male-sample-image.jpg" alt="An image of a man">
                    </div>
                    <div class="carousel-item" style="display: none">
                        <img id="imageTwo" src="./Images/woman-sample-image.jpg" alt="An image of a woman">
                    </div>
                    <div class="carousel-item" style="display: none">
                        <img id="imageThree" src="./Images/KhaineFatHead.jpg" alt="An image of Khaine">
                    </div>
                </div>
            <div class="occupation">
                <p>Full-Stack Developer</p>
            </div>
            <div class="userComment">
                <p id="userComment">This website is amazing - really useful learning experience. I hope the creator continues on his developer journey and we see more from him in the future!</p>
            </div>
                    <div class="userAction">
                        <button type="button" id="buttonLeft" onclick="previousReview()">Previous</button>
                        <button type="button" id="buttonRight" onclick="nextReview()">Next</button>
                    </div>
        </div>
</body>
<script src="script.js"></script>
</html>

CSS:


.heading {
    width: 100vw;
    text-align: center;
    margin-left: auto;
    margin-right: auto;
    font-size: 30px;
} 

.name {
    margin: auto;
    text-align: center;
    color: #632A7A;
    font-size: 2rem;
}
.occupation {
    margin: auto;
    text-align: center;
    color: #632A7A;
    font-size: 1.6rem;
    text-align: center;
}

.occupation p {
    border: 1.5px solid white;
    border-radius: 20%;
    width: 300px;
    display: inline-block;
    text-align: center;
    
}

#buttonLeft, 
#buttonRight {
    width: 200px;
    height: 40px;
    display: inline-block;
    border: 3px solid black;
    background-color: #632A7A;
    border-radius: 15%;
    margin-bottom: 20px;
}

#buttonLeft:hover, 
#buttonRight:hover {
    box-shadow: 0 12px 16px 0 rgba(0,0,0,0.24), 0 17px 50px 0 rgba(0,0,0,0.19);
}

h1 {
    text-align: center;
}

#buttonLeft, 
#buttonRight {
  color: #fff;
  background-color: #632A7A;
  background-image: radial-gradient(93% 87% at 87% 89%, rgba(0, 0, 0, 0.23) 0%, transparent 86.18%), radial-gradient(66% 66% at 26% 20%, rgba(255, 255, 255, 0.55) 0%, rgba(255, 255, 255, 0) 69.79%, rgba(255, 255, 255, 0) 100%);
  box-shadow: inset -3px -3px 9px rgba(255, 255, 255, 0.25), inset 0px 3px 9px rgba(255, 255, 255, 0.3), inset 0px 1px 1px rgba(255, 255, 255, 0.6), inset 0px -8px 36px rgba(0, 0, 0, 0.3), inset 0px 1px 5px rgba(255, 255, 255, 0.6), 2px 19px 31px rgba(0, 0, 0, 0.2);
  border-radius: 14px;
  font-size: 16px;
  border: 0;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  cursor: pointer;
}
.userAction {
    text-align: center;
}

#userComment {
    font-size: 1.25rem;
    text-align: center;
    display: inline-block;
    padding-left: 50px;
    padding-right: 50px;
}

.carousel {
    max-width: 400px;
    max-height: 300px;
    margin: auto;
}
.carousel img {
    border: solid 1px black;
    height: 300px;
    width: 400px;
}
.carousel-item:first-child {
    display: block;
}
.carousel-item {
    display: none;
}


body {
    font-family: sans-serif;
    color: white;
    margin: auto;
} 

html {
    min-height: 100%;
    background-color: rgb(12,12,112);
    background-image: url("./Images/background-image.jpg");
    background-repeat: no-repeat;
    background-size: cover;
    background-blend-mode: multiply;
}

Where is the css code you wrote for handling the hidden and visible classes?

I included this in the HTML code as I figured that it would be easier to use classList.add/remove later on. I used style=“display: block” or style=“display: none”

You haven’t answered my question?

Your js code is relying on this logic

function updateSlidePosition() {
    for (let slide of slides) {
        slide.classList.remove('visible');
        slide.classList.add('hidden');
    }

    slides[slidePosition].classList.add('visible');
}

You are hoping this logic will do something interesting to your html elements correct?
All I see is that you are modifying the classes. Where is the css code that reacts in an interesting way to these classes?

I had to go away and look at classLists, as I clearly did not understand what they are used for. I figured they were a way to alter the attributes in a HTML element directly :man_facepalming:

I now see that they require the code to be taken directly from the CSS stylesheet and it’s respective class. I have now added the following:

.hidden { display: none; }
.visible { display: block; }

To my CSS sheet.

This is my JS:

let slidePosition = 0;
const slides = document.getElementsByClassName('carousel-item');
let totalSlides = slides.length;

function nextReview() {
    if (slidePosition == totalSlides - 1) {
        slidePosition = 0; 
    } else {
        slidePosition++;
    }
    updateSlidePosition();
}

function previousReview() {
    if (slidePosition == 0) {
        slidePosition = 0;
    } else {
        slidePosition--;
    }
    
    updateSlidePosition();
}

function updateSlidePosition() {
    for (let slide of slides) {
        slide.classList.remove('visible');
        slide.classList.add('hidden');
    }

    slides[slidePosition].classList.add('visible');
}

and HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" type="text/css" href="styles.css">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">    
    <title>Review Page</title>
</head>
<body>
    <div class="heading">
        <h1>Our Reviews:</h1>
        <hr>
    </div>
            <div class="name">
                <h2>John Doe</h2>
            </div>
                <div class="carousel">
                    <div class="carousel-item">
                        <img id="defVisible" src="./Images/male-sample-image.jpg" alt="An image of a man">
                    </div>
                    <div class="carousel-item">
                        <img id="imageTwo" src="./Images/woman-sample-image.jpg" alt="An image of a woman">
                    </div>
                    <div class="carousel-item">
                        <img id="imageThree" src="./Images/KhaineFatHead.jpg" alt="An image of Khaine">
                    </div>
                </div>
            <div class="occupation">
                <p>Full-Stack Developer</p>
            </div>
            <div class="userComment">
                <p id="userComment">This website is amazing - really useful learning experience. I hope the creator continues on his developer journey and we see more from him in the future!</p>
            </div>
                    <div class="userAction">
                        <button type="button" id="buttonLeft" onclick="previousReview()">Previous</button>
                        <button type="button" id="buttonRight" onclick="nextReview()">Next</button>
                    </div>
        </div>
</body>
<script src="script.js"></script>
</html>

But I am still seeing absolutely no changes. I would have expected to, at least, see some form of visual change. Even if it was simply the image disappearing.

Thanks again for taking a look - could you give me another pointer as to why this is not working?

the location of the script tag is wrong. It needs to be inside the body element (move it up by one line)