Carousel in Vanilla JavaScript I finally got my carousel to work in JavaScript, and I want to know what you guys think about it and what I can do better.



var reviews = document.getElementsByClassName('review');
var leftArrow = document.getElementsByClassName('arrow')[0];
var rightArrow = document.getElementsByClassName('arrow')[1];

var currentReview;
var nextReview;

function carousel(direction) {
  for (var i = 0; i &lt; reviews.length; i++) {
    if (reviews[i].classList.contains("show")) {
      currentReview = reviews[i];
      if (direction == 'forward') {
        if (i + 1 &gt; reviews.length - 1) {
          nextReview = reviews[0];
        } else {
          nextReview = reviews[i + 1];
        }
      } else {
        if (i - 1 &lt; 0) {
          nextReview = reviews[reviews.length - 1];
        } else {
          nextReview = reviews[i - 1];
        }
      }
    }
  }

  currentReview.classList.remove("show");
  nextReview.classList.add("show");
}

leftArrow.onclick = function() {
  carousel('backward');
}
rightArrow.onclick = function() {
  carousel('forward');
}
* {
  font-family: Arial;
}

.carousel {
  display: flex;
  align-items: center;
  justify-content: center;
}

.review {
  display: none;
  text-align: center;
}

.show {
  display: block;
}

.arrow {
  margin-left: 25vw;
  margin-right: 25vw;
}

.arrow-left {
  width: 0;
  height: 0;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  border-right: 10px solid black;
}

.arrow-right {
  width: 0;
  height: 0;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  border-left: 10px solid black;
}
&lt;div class="carousel"&gt;
  &lt;div class="arrow-left arrow"&gt;&lt;/div&gt;
  &lt;div class="reviews"&gt;
    &lt;div class="review show"&gt;
      &lt;h1 class="title"&gt;Title1&lt;/h1&gt;
    &lt;/div&gt;
    &lt;div class="review"&gt;
      &lt;h1 class="title"&gt;Title2&lt;/h1&gt;
    &lt;/div&gt;
    &lt;div class="review"&gt;
      &lt;h1 class="title"&gt;Title3&lt;/h1&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="arrow-right arrow"&gt;&lt;/div&gt;




It can also be demonstrated in this JSFiddle
Arrow elements

There are two elements for the arrows, and presuming there is only one of each type (i.e. one left, one right) then it would be more appropriate to use an id attribute for distinguishing between those two.

Instead of 


&lt;div class="arrow-left arrow"&gt;&lt;/div&gt;
&lt;div class="arrow-right arrow"&gt;&lt;/div&gt;



use the id attribute:

&lt;div class="arrow" id="arrow-left"&gt;&lt;/div&gt;
&lt;div class="arrow" id="arrow-right"&gt;&lt;/div&gt;


And instead of selecting elements by class name and taking the first one:


var leftArrow = document.getElementsByClassName('arrow')[0];
var rightArrow = document.getElementsByClassName('arrow')[1];



select them using document.getElementById():

var leftArrow = document.getElementById('arrow-left');
var rightArrow = document.getElementById('arrow-right');


Obviously this would require the CSS to be updated as well.

Direction parameter

There are only two possible values for direction, so it could be changed to a boolean like forward that defaults to true (default parameters is a feature of ecmascript-6 so be aware of the browser compatibility).

function carousel(forward = true) {
  if (forward) {
    //move forward 
  }
  else { 
    //move backward
  }


Simplify onclick event handlers

After making the first parameter for carousel a boolean that defaults to true (for the direction), the onclick handlers can be simplified to function references. false can be tied to the leftArrow handler by employing a partially applied function with Function.bind()

leftArrow.onclick = carousel.bind(null, false);
rightArrow.onclick = carousel;


If there was a need to have multiple event handlers on each element then addEventListener() could be used:

leftArrow.addEventListener('click', carousel.bind(null, false));
rightArrow.addEventListener('click', carousel);


Simplify logic for current and next

Instead of looping through the reviews, select the elements that have class name show (should only be one):

var shownReviews = document.getElementsByClassName('show');


That will be a live HTMLCollection, meaning that it updates as the DOM is updated, so there is no need to re-query it. 

Then you can utilize shownReviews[0] - this can be used to set currentReview. Then when forward is true the value for nextReview can be set utilizing nextElementSibling or if that is null using parentElement.firstElementChild (and conversely using previousElementSibling and lastElementChild when forward is false).

function carousel(forward = true) {
  currentReview = shownReviews[0];
  if (forward) {
    nextReview = currentReview.nextElementSibling || currentReview.parentElement.firstElementChild;  
  }
  else {
    nextReview = currentReview.previousElementSibling || currentReview.parentNode.lastElementChild;   
  }
  currentReview.classList.remove("show");
  nextReview.classList.add("show");
}


Simplify CSS

The following styles can be moved out of each of the rulesets for the arrows and moved into the ruleset for .arrow:


width: 0;
height: 0;
border: 10px solid transparent; 



Then the rulesets for the arrows becomes a single style:

#arrow-left {
  border-right: 10px solid black;
}

#arrow-right {
  border-left: 10px solid black;
}


The margin styles for .arrow can be combined to a single style using two values: 

margin: 0 25vw; /* top &amp; bottom: 0, left &amp; right: 25vw */




Rewrite

Below is simplified code using the advice above.



var shownReviews = document.getElementsByClassName('show');
var leftArrow = document.getElementById('arrow-left');
var rightArrow = document.getElementById('arrow-right');

var currentReview;
var nextReview;

function carousel(forward = true) {
  currentReview = shownReviews[0];
  if (forward) {
    nextReview = currentReview.nextElementSibling || currentReview.parentElement.firstElementChild;  
  }
  else {
    nextReview = currentReview.previousElementSibling || currentReview.parentNode.lastElementChild;   
  }
  currentReview.classList.remove("show");
  nextReview.classList.add("show");
}

leftArrow.onclick = carousel.bind(null, false);

rightArrow.onclick = carousel;
* {
  font-family: Arial;
}

.carousel {
  display: flex;
  align-items: center;
  justify-content: center;
}

.review {
  display: none;
  text-align: center;
}

.show {
  display: block;
}

.arrow {
  border: 10px solid transparent;
  width: 0;
  height: 0;
  margin: 0 25vw;
}

#arrow-left {
  border-right: 10px solid black;
}

#arrow-right {
  border-left: 10px solid black;
}
&lt;div class="carousel"&gt;
  &lt;div class="arrow" id="arrow-left"&gt;&lt;/div&gt;
  &lt;div class="reviews"&gt;
    &lt;div class="review show"&gt;
      &lt;h1 class="title"&gt;Title1&lt;/h1&gt;
    &lt;/div&gt;
    &lt;div class="review"&gt;
      &lt;h1 class="title"&gt;Title2&lt;/h1&gt;
    &lt;/div&gt;
    &lt;div class="review"&gt;
      &lt;h1 class="title"&gt;Title3&lt;/h1&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="arrow" id="arrow-right"&gt;&lt;/div&gt;
&lt;/div&gt;