In a previous post, I wrote about creating an image carousel using basic web tech: HTML, CSS, and vanilla JavaScript. No frameworks, no jQuery. This is an update to that. The major difference is that it supports multiple carousels on the same page. I also added a try/catch, in case no carousel data is found in the database. I recently used this implementation on a WordPress site. Each carousel was a post (of a custom carousel post-type), that had each image attached. On that post-type archive page, I looped through the posts, and created a separate carousel for each.
Here is the updated JavaScript.
try{
var galleries = document.getElementsByClassName("carousel-class");
for(var i = 0; i < galleries.length; i++){
showGalleries(galleries.item(i), 0);
}
}catch(e){
console.log(e);
}
function showGalleries(gallery, galleryIndex){
var galleryDots = gallery.getElementsByClassName("dot-button");
var gallerySlides = gallery.getElementsByClassName("my-slide");
if (galleryIndex < 0){galleryIndex = gallerySlides.length-1}
galleryIndex++;
for(var ii = 0; ii < gallerySlides.length; ii++){ gallerySlides[ii].style.display = "none"; galleryDots[ii].classList.remove('active-dot'); } if (galleryIndex > gallerySlides.length){galleryIndex = 1}
gallerySlides[galleryIndex-1].style.display = "block";
var resizeEvent = new Event('resize');
window.dispatchEvent(resizeEvent);
galleryDots[galleryIndex-1].classList.add('active-dot');
//hide gallery navigation, if there is only 1
if(gallerySlides.length < 2){
var dotContainer = gallery.getElementsByClassName("dots");
var arrowContainer = gallery.getElementsByClassName("gallery-arrows");
dotContainer[0].style.display = "none";
arrowContainer[0].style.display = "none";
}
gallery.setAttribute("data", galleryIndex);
}
//gallery dots
document.addEventListener('click', function (event) {
if (!event.target.matches('.carousel-class .dot-button')){ return; }
var index = event.target.getAttribute("data");
var parentGallery = event.target.closest(".carousel-class")
showGalleries(parentGallery, index);
}, false);
//gallery arrows
//left arrow
document.addEventListener('click', function (event) {
if (!event.target.matches('.fa-arrow-left')){ return; }
var parentGallery = event.target.closest(".carousel-class")
var galleryIndex = parentGallery.getAttribute("data");
galleryIndex = galleryIndex - 2;
showGalleries(parentGallery, galleryIndex);
}, false);
//right arrow
document.addEventListener('click', function (event) {
if (!event.target.matches('.fa-arrow-right')){ return; }
var parentGallery = event.target.closest(".carousel-class")
var galleryIndex = parentGallery.getAttribute("data");
showGalleries(parentGallery, galleryIndex);
}, false);
You’ll notice that each carousel section has a data attribute assigned, so our JS knows which one to affect. This version also includes left and right navigation arrows, in addition to the navigation dots we already had.
HTML:
<div class="ap-carousel" data="0">
<?php $num_slides = 0; foreach($posts as $post){ $num_slides++; ?>
<div class="ap-slide">
<a href="<?php the_permalink($post->ID); ?>" title="<?php the_title(); ?>">
<img src="<?php echo esc_url(get_the_post_thumbnail_url($post->ID)); ?>" class="zoom">
</a>
</div>
<?php } ?>
<div class="nav-dots">
<?php $active = "active-dot"; for($x = 0; $x < $num_slides; $x++){ ?>
<div class="dot"><button data="<?php echo $x; ?>" type="button" class="dot-button <?php echo $active; $active = ''; ?>">b</button></div>
<?php } ?>
</div>
<div class="gallery-arrows">
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-right"></i>
</div>
</div>
I emphasize simplicity when building solutions. I avoid including superfluous code libraries when a vanilla technique works. It’s helpful to keep track of solutions I engineer, and try to reuse them where they fit. And when they need to be adjusted to work with a new problem, I enhance them while still trying to avoid complexity.