{"id":256,"date":"2019-10-08T23:16:13","date_gmt":"2019-10-08T23:16:13","guid":{"rendered":"https:\/\/www.antpace.com\/blog\/?p=256"},"modified":"2025-08-25T13:58:59","modified_gmt":"2025-08-25T13:58:59","slug":"image-carousel-update","status":"publish","type":"post","link":"https:\/\/www.antpace.com\/blog\/image-carousel-update\/","title":{"rendered":"Image carousel &#8211; update"},"content":{"rendered":"<p>In <a href=\"https:\/\/www.antpace.com\/blog\/easy-image-carousel\/\">a previous post<\/a>, 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.<\/p>\n<p>Here is the updated JavaScript.<\/p>\n<pre>try{\n    var galleries = document.getElementsByClassName(\"carousel-class\");\n    for(var i = 0; i &lt; galleries.length; i++){\n        showGalleries(galleries.item(i), 0);\n    }\n}catch(e){\n    console.log(e);\n}\n\nfunction showGalleries(gallery, galleryIndex){\n    var galleryDots = gallery.getElementsByClassName(\"dot-button\");\n    var gallerySlides = gallery.getElementsByClassName(\"my-slide\");\n    if (galleryIndex &lt; 0){galleryIndex = gallerySlides.length-1}\n    galleryIndex++;\n    for(var ii = 0; ii &lt; gallerySlides.length; ii++){ gallerySlides[ii].style.display = \"none\"; galleryDots[ii].classList.remove('active-dot'); } if (galleryIndex &gt; gallerySlides.length){galleryIndex = 1}\n    gallerySlides[galleryIndex-1].style.display = \"block\";\n    var resizeEvent = new Event('resize');\n    window.dispatchEvent(resizeEvent);\n    galleryDots[galleryIndex-1].classList.add('active-dot');\n    \/\/hide gallery navigation, if there is only 1\n    if(gallerySlides.length &lt; 2){\n        var dotContainer = gallery.getElementsByClassName(\"dots\");\n        var arrowContainer = gallery.getElementsByClassName(\"gallery-arrows\");\n        dotContainer[0].style.display = \"none\";\n        arrowContainer[0].style.display = \"none\";\n    }\n    gallery.setAttribute(\"data\", galleryIndex);\n}\n\n\/\/gallery dots\ndocument.addEventListener('click', function (event) {\n    if (!event.target.matches('.carousel-class .dot-button')){ return; }\n    var index = event.target.getAttribute(\"data\");\n    var parentGallery = event.target.closest(\".carousel-class\")\n    showGalleries(parentGallery, index);\n\n}, false);\n\n\/\/gallery arrows\n\n\/\/left arrow\ndocument.addEventListener('click', function (event) {\n    if (!event.target.matches('.fa-arrow-left')){ return; }\n    var parentGallery = event.target.closest(\".carousel-class\")\n    var galleryIndex = parentGallery.getAttribute(\"data\");\n    galleryIndex = galleryIndex - 2;\n\n    showGalleries(parentGallery, galleryIndex);\n}, false);\n\n\/\/right arrow\ndocument.addEventListener('click', function (event) {\n    if (!event.target.matches('.fa-arrow-right')){ return; }\n    var parentGallery = event.target.closest(\".carousel-class\")\n    var galleryIndex = parentGallery.getAttribute(\"data\");\n\n    showGalleries(parentGallery, galleryIndex);\n}, false);\n\n<\/pre>\n<p>You&#8217;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.<\/p>\n<p>HTML:<\/p>\n<pre>&lt;div class=\"ap-carousel\" data=\"0\"&gt;\n\n&lt;?php $num_slides = 0; foreach($posts as $post){ $num_slides++; ?&gt;\n\n\t&lt;div class=\"ap-slide\"&gt;\n\t\t&lt;a href=\"&lt;?php the_permalink($post-&gt;ID); ?&gt;\" title=\"&lt;?php the_title(); ?&gt;\"&gt;\n\t\t\t&lt;img src=\"&lt;?php echo esc_url(get_the_post_thumbnail_url($post-&gt;ID)); ?&gt;\" class=\"zoom\"&gt;\n\t\t&lt;\/a&gt;\n\t&lt;\/div&gt;\n\n&lt;?php } ?&gt;\n&lt;div class=\"nav-dots\"&gt;\n\t&lt;?php $active = \"active-dot\"; for($x = 0; $x &lt; $num_slides; $x++){ ?&gt;\n\t\t&lt;div class=\"dot\"&gt;&lt;button data=\"&lt;?php echo $x; ?&gt;\" type=\"button\" class=\"dot-button &lt;?php echo $active; $active = ''; ?&gt;\"&gt;b&lt;\/button&gt;&lt;\/div&gt;\n\t&lt;?php } ?&gt;\n&lt;\/div&gt;\n&lt;div class=\"gallery-arrows\"&gt;\n    &lt;i class=\"fas fa-arrow-left\"&gt;&lt;\/i&gt;\n    &lt;i class=\"fas fa-arrow-right\"&gt;&lt;\/i&gt;\n&lt;\/div&gt;\n\n\n&lt;\/div&gt;\n<\/pre>\n<p>I emphasize simplicity when building solutions. I avoid including\u00a0superfluous code libraries when a vanilla technique works. It&#8217;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.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.antpace.com\/blog\/image-carousel-update\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Image carousel &#8211; update&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3155,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-256","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development"],"_links":{"self":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/256","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/comments?post=256"}],"version-history":[{"count":1,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/256\/revisions"}],"predecessor-version":[{"id":3156,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/256\/revisions\/3156"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/media\/3155"}],"wp:attachment":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/media?parent=256"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/categories?post=256"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/tags?post=256"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}