Product image carousel in shop categories
The individual product pages have nifty arrows on the side of the image preview to scroll through the images of a product, these are called “carousel”. I wanted that functionality extended to the category view - to be able to quickly scroll product images without entering the individual product page.
HTML:
JAVASCRIPT: <script> document.addEventListener('DOMContentLoaded', function() { const subString = 'shop'; const subStringTwo = 'shop/p/'; const getURL = window.location.href; if (getURL.includes(subString) && !getURL.includes(subStringTwo)) { const headerActions = document.querySelector('.header-actions'); let isTouch = false; function checkHeader() { const styles = window.getComputedStyle(headerActions); isTouch = styles.getPropertyValue('display') !== 'flex'; } checkHeader(); function cloneImageArrows() { const products = document.querySelectorAll('.product-lists-item'); products.forEach((product, index) => { const allImages = product.querySelectorAll('.grid-item-image'); if (allImages.length >= 2) { const clonedElement = document.createElement('div'); const productImage = product.querySelector('.grid-image'); productImage.prepend(clonedElement); clonedElement.id = `carousel${index + 1}`; clonedElement.classList.add('carousel', 'categoryArrows', 'ProductItem-gallery-carousel-controls'); const leftArrow = document.createElement('div'); const rightArrow = document.createElement('div'); clonedElement.appendChild(leftArrow); clonedElement.appendChild(rightArrow); leftArrow.classList.add('arrowButton', 'arrowPrev', 'ProductItem-gallery-prev', 'product-item-gallery-carousel-control'); rightArrow.classList.add('arrowButton', 'arrowNext', 'ProductItem-gallery-next', 'product-item-gallery-carousel-control'); function adjustImageArrows() { if (!isTouch) { leftArrow.style.position = 'absolute'; leftArrow.style.left = '-14%'; leftArrow.style.transform = 'scale(0.33)'; rightArrow.style.position = 'absolute'; rightArrow.style.right = '-14%'; rightArrow.style.transform = 'scale(0.33)'; } else { leftArrow.style.position = 'absolute'; leftArrow.style.left = '0%'; leftArrow.style.transform = 'scale(1.2)'; rightArrow.style.position = 'absolute'; rightArrow.style.right = '0%'; rightArrow.style.transform = 'scale(1.2)'; } } adjustImageArrows(); allImages.forEach((image, i) => { if (i !== 0) image.style.display = 'none'; }); productImage.addEventListener('click', function(event) { const clickedArrow = event.target.closest('.arrowButton'); if (!clickedArrow) return; event.preventDefault(); const direction = clickedArrow.classList.contains('arrowPrev') ? 'left' : 'right'; handleArrowClick(direction, allImages); }); function handleArrowClick(direction, images) { const imagesArray = Array.from(images); const activeImage = imagesArray.find(image => image.style.display === 'block'); const currentIndex = imagesArray.indexOf(activeImage); let newIndex; if (direction === 'left') { newIndex = currentIndex > 0 ? currentIndex - 1 : imagesArray.length - 1; } else { newIndex = currentIndex < imagesArray.length - 1 ? currentIndex + 1 : 0; } activeImage.style.display = 'none'; activeImage.classList.remove('active'); imagesArray[newIndex].classList.add('active'); imagesArray[newIndex].style.display = 'block'; imagesArray[newIndex].classList.remove('grid-image-hover'); } window.addEventListener('resize', function() { const prevIsTouch = isTouch; checkHeader(); if (isTouch !== prevIsTouch) { adjustImageArrows(); } }); } }); } cloneImageArrows(); } }); </script>
CSS: //PRODUCT CATEGORY CAROUSEL// .product-item-gallery-carousel-control::after { font-weight: bold; border-right: 3px solid black !important; border-top: 3px solid black !important; border-image: linear-gradient(45deg, rgba(0,0,0,0) 50%, rgba(0,0,0,1) 100%); border-image-slice: 1; background-size: contain; background-position: center; background-repeat: no-repeat; transition: all 1s ease; } .product-item-gallery-carousel-control:hover::after { background: linear-gradient(45deg, rgba(0,0,0,0) 50%, rgba(255,199,0,0.8) 100%,); } .carousel { z-index: 9999; position: absolute; width: 100%; height: 100%; display: flex; align-items: center; } .grid-item-image { color: transparent; opacity: 0% !important; transition: all 1s ease-in-out !important; } .grid-item-image.active { opacity: 100% !important; display: block; }
COMMENTS:
Leave a comment: