3
\$\begingroup\$

As a beginner project, I've start working on this carousel slider that would slide through an image and a testimonial on click.

The number of images and content slides would always be the same number. I got the javascript to work but I feel like I'm repeating myself on some of my helper classes. I've tried to rework them so I could use some higher order function to achieve what I'm trying to do but I haven't had any luck. If anyone could review this or point me in the right direction that would be great.

JSFiddle Link here: https://jsfiddle.net/ej87pdsb/

// CAROUSEL GALLERY
const carouselBtns = document.querySelectorAll(`[class*='arr-']`);
const carouselImages = Array.from(document.querySelectorAll('.carousel-images img'));
const carouselContent = Array.from(document.querySelectorAll('.carousel-content .carousel-content-item'));
let currentSlide = 0;

function activateSlider(e) {
    if (e.target.classList.contains('arr-next')) {
        arrNextBtn();
    } else {
        arrPrevBtn();
    }
}

function arrNextBtn() {
    if (currentSlide == carouselImages.length - 1) {
        currentSlide = 0;
    } else {
        currentSlide++;
    }
    addRemoveHideClass();
}

function arrPrevBtn() {
    if (currentSlide == 0) {
        currentSlide = carouselImages.length - 1;
    } else {
        currentSlide--;
    }
    addRemoveHideClass();
}

function addRemoveHideClass() {
    carouselImages.filter(function (img) {
        if (img == foundImage()) {
            img.classList.remove('hide');
        } else {
            img.classList.add('hide');
        }
    });
    carouselContent.filter(function (content) {
        if (content == foundContent()) {
            content.classList.remove('hide');
        } else {
            content.classList.add('hide');
        }
    });
}

function foundImage() {
    const imageMatch = carouselImages.find(function findMatchingImage(img, index) {
        if (index == currentSlide) {
            return img;
        }
    });
    return imageMatch;
}

function foundContent() {
    const contentMatch = carouselContent.find(function findMatchingContent(content, index) {
        if (index == currentSlide) {
            return content;
        }
    });
    return contentMatch;
}

carouselBtns.forEach(function (btn) {
    btn.addEventListener('click', activateSlider);
});
/* RESET STUFF */
html {
    box-sizing: border-box;
    scroll-behavior: smooth;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}


/** FLEX / POSITIONING ON MOBILE **/
.carousel {
    display: flex;
    flex-flow: column wrap;
    align-items: flex-start;
}

/* Previous and Next Arrow Positioning */
.carousel-arrs [class*='arr-'] {
    position: absolute;
    top: 37%;
    background: none;
    border: none;
    z-index: 9999;
}

.carousel-arrs .arr-prev {
    left: -2%;
}

.carousel-arrs .arr-next {
    right: -2%;
}

/** SETTING SCROLLING CONTENT INLINE, HIDDING OVERFLOWS AND SETTING HEIGHTS AND WIDTHS FOR MAIN CONTENT SECTIONS **/
.carousel-content,
.carousel-images {
    display: inline-flex;
  overflow: hidden;
  width:100%;
}

.carousel-content {
    height: 450px;
    min-height: 100%;
}

.carousel-images img {
    width: 100vw;
    min-width: 100%;
    height: 310px;
    object-fit: cover;
    border-radius: 0.25rem 0.25rem 0% 0%; /* Rem Values Taken from BS4 .rounded class*/
}

.carousel-content-item {
  min-width: 100%;
  padding: 50px 40px;
}

/** MOBILE / TYPOGRAPHY / PADDING / MARGINS STYLING **/

.carousel {
  border-radius: .25rem!important;
    background-color: rgb(255, 255, 255);
    box-shadow: 0 50px 100px -20px rgba(50, 50, 93, 0.25),
        0 30px 60px -30px rgba(0, 0, 0, 0.3),
        inset 0 -2px 6px 0 rgba(10, 37, 64, 0.35);
}

.carousel-arrs [class*='arr-'] svg {
    background-color: #fff;
    border-radius: 50%;
    color: #00aeef;
    box-shadow: none;
    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.105);
    transition: cubic-bezier(0.23, 1, 0.32, 1);
    pointer-events: all;
}

.carousel-arrs [class*='arr-'] svg:hover {
    color: #f4af38;
    transform: translateY(-2px);
}

/* Transitions and Hide Class Styling */
.carousel-images img, .carousel-content .carousel-content-item {
    transition: visibility 0s, opacity 0.3s ease-in;
}

.hide {
    position: absolute;
    opacity: 0;
    visibility: hidden;
}

/** STYLE OVERRIDES FOR 768PX AND ABOVE  **/
@media (min-width: 768px) {

  /** FLEX / POSITIONING **/

    .carousel {
        flex-flow: row nowrap;
    align-items: stretch;
    overflow:hidden;
  }

  /* Previous and Next Arrow Positioning */
    .carousel-arrs [class*='arr-'] {
        top: 50%;
  }

    .carousel-arrs .arr-prev {
        left: 0%;
    }
    .carousel-arrs .arr-next {
        right: 0%;
  }

  /* SETTING SCROLLING CONTENT INLINE, HIDDING OVERFLOWS AND SETTING HEIGHTS AND WIDTHS FOR MAIN CONTENT SECTIONS */
  .carousel-content {
        height: 550px;
        align-items: center;
  }

  .carousel .carousel-images,
    .carousel .carousel-content {
        flex-basis: 50%;
    }

  /** MOBILE / TYPOGRAPHY / PADDING / MARGINS STYLING **/
    .carousel-images {
        background-color: #00afef44;
        -webkit-clip-path: polygon(0 0, 100% 0%, 78% 100%, 0% 100%);
        clip-path: polygon(0 0, 100% 0%, 78% 100%, 0% 100%);
    }
    .carousel-images img {
        min-height: 100%;
        -webkit-clip-path: polygon(0 0, 100% 0%, 75% 100%, 0% 100%);
        clip-path: polygon(0 0, 100% 0%, 75% 100%, 0% 100%);
  }

    .carousel-content-item {
        padding: 80px 70px 80px 0px;
    }
}
<section class="carousel">
  <div class="carousel-arrs">
    <button class="arr-prev">
      <svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" fill="currentColor"
        class="bi bi-arrow-left-circle-fill " viewBox="0 0 16 16">
        <path
          d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0zm3.5 7.5a.5.5 0 0 1 0 1H5.707l2.147 2.146a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708l3-3a.5.5 0 1 1 .708.708L5.707 7.5H11.5z" />
      </svg>
    </button>
    <button class="arr-next"><svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" fill="currentColor"
        class="bi bi-arrow-right-circle-fill" viewBox="0 0 16 16">
        <path
          d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zM4.5 7.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H4.5z" />
      </svg></button>
  </div>

  <div class="carousel-images">
    <img src="https://stripe.com/img/v3/atlas_v2/user_photos/metafused.jpg" class="img-fluid center-block carousel-img" alt="">
    <img src="https://stripe.com/img/v3/atlas_v2/user_photos/sheleadsafrica.jpg" class="img-fluid center-block carousel-img"
      alt="">
    <img src="https://stripe.com/img/v3/atlas_v2/user_photos/coin_tracker.jpg" class="img-fluid center-block carousel-img"
      alt="">
  </div>

  <div class="carousel-content">
    <div class="carousel-content-item">
      
      <p class="font-weight-light h3 text-muted font-italic">Lorem ipsum dolor sit amet consectetur adipisicing elit. Laboriosam neque modi dolorem incidunt voluptatibus nostrum quae quo ad perferendis accusamus!
      </p>
      <p><strong class="h4">TEST
        </strong> <br>
TEST          </p>
    </div>
    <div class="carousel-content-item">
     
      <p class="font-weight-light h3 text-muted font-italic">Lorem ipsum dolor sit amet consectetur adipisicing elit. Nostrum dolor tempore rerum est temporibus, amet cum. Quos distinctio impedit ipsum.</p>
      <p><strong class="h4">test</strong> <br>
        test Lorem, ipsum dolor.

      </p>

    </div>
    <div class="carousel-content-item">
      
      <p class="font-weight-light h3 text-muted font-italic">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quibusdam distinctio omnis odio dicta ad maiores accusantium voluptatibus cum nemo expedita?</p>
      <p><strong class="h4">test</strong> <br>
        test Lorem, ipsum dolor.

      </p>
    </div>
  </div>
</section>

\$\endgroup\$
1
\$\begingroup\$

The function addRemoveHideClass() uses to calls to the array method filter(). That method "creates a new array with all elements that pass the test implemented by the provided function." 1 That method is meant to filter an array of elements that match a certain criteria so it returns an array 2. If you just want to iterate over the elements in the array, you can use use .forEach(), or a for...of loop loop could be used instead. Also, each iteration of those loops calls foundImage() and foundContent(). This is quite inefficient. It would be more efficient to store the value of those calls outside the loop and use the stored value inside the loop.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.