1document.addEventListener('DOMContentLoaded', function () { 2 const track = document.getElementById('sliderTrack'); 3 const nextBtn = document.getElementById('nextBtn'); 4 const prevBtn = document.getElementById('prevBtn'); 5 const gap = 24; 6 let currentIndex = 0; 7 let cards = document.querySelectorAll('.testimonial-card'); 8 let autoSlideInterval; 9 10 // Get visible cards 11 function getVisibleCards() { 12 return window.innerWidth >= 992 ? 2 : 1; 13 } 14 let visibleCards = getVisibleCards(); 15 16 // Clone cards for infinite effect 17 function cloneCards() { 18 visibleCards = getVisibleCards(); 19 for (let i = 0; i < visibleCards; i++) { 20 const clone = cards[i].cloneNode(true); 21 track.appendChild(clone); 22 } 23 cards = document.querySelectorAll('.testimonial-card'); 24 } 25 cloneCards(); 26 27 // Update slider position 28 function updateSliderPosition(animate = true) { 29 const cardWidth = cards[0].offsetWidth; 30 const moveAmount = (cardWidth + gap) * currentIndex; 31 track.style.transition = animate ? "transform 0.5s ease-in-out" : "none"; 32 track.style.transform = `translateX(-${moveAmount}px)`; 33 } 34 35 // NEXT 36 function goNext() { 37 currentIndex++; 38 updateSliderPosition(); 39 if (currentIndex === cards.length - visibleCards) { 40 setTimeout(() => { 41 currentIndex = 0; 42 updateSliderPosition(false); 43 }, 500); 44 } 45 } 46 // PREV 47 function goPrev() { 48 if (currentIndex === 0) { 49 currentIndex = cards.length - visibleCards - 1; 50 updateSliderPosition(false); 51 } else { 52 currentIndex--; 53 } 54 setTimeout(() => { 55 updateSliderPosition(); 56 }, 10); 57 } 58 59 // BUTTON EVENTS 60 nextBtn.addEventListener('click', goNext); 61 prevBtn.addEventListener('click', goPrev); 62 63 // AUTO SLIDE 64 function startAutoSlide() { 65 autoSlideInterval = setInterval(() => { 66 goNext(); // reuse logic 67 }, 3000); 68 } 69 function stopAutoSlide() { 70 clearInterval(autoSlideInterval); 71 } 72 73 // INIT 74 updateSliderPosition(false); 75 startAutoSlide(); 76 77 // PAUSE ON HOVER 78 track.addEventListener('mouseenter', stopAutoSlide); 79 track.addEventListener('mouseleave', startAutoSlide); 80 81 // RESIZE FIX 82 window.addEventListener('resize', () => { 83 stopAutoSlide(); 84 currentIndex = 0; 85 // Reset track (remove clones safely) 86 track.innerHTML = ''; 87 cards.forEach(card => track.appendChild(card)); 88 cards = document.querySelectorAll('.testimonial-card'); 89 cloneCards(); 90 updateSliderPosition(false); 91 startAutoSlide(); 92 }); 93});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.