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>