1/** 2 * Mobile Testimonials Carousel 3 */ 4(function() { 5 'use strict'; 6 7 function initMobileCarousel() { 8 var mobileCarousel = document.querySelector('.js-testimonials-mobile'); 9 if (!mobileCarousel) return; 10 11 // ÐÑовеÑÑем видимоÑÑÑ ÑлеменÑа 12 if (mobileCarousel.offsetParent === null) { 13 // ÐÐ»ÐµÐ¼ÐµÐ½Ñ ÑкÑÑÑ, не иниÑиализиÑÑем 14 return; 15 } 16 17 var container = mobileCarousel.querySelector('.c-testimonials-mobile__container'); 18 var track = mobileCarousel.querySelector('.js-testimonials-mobile-track'); 19 var slides = mobileCarousel.querySelectorAll('.js-testimonials-mobile-slide'); 20 var prevBtn = mobileCarousel.querySelector('.js-testimonials-mobile-prev'); 21 var nextBtn = mobileCarousel.querySelector('.js-testimonials-mobile-next'); 22 var companyLogo = mobileCarousel.querySelector('.js-testimonials-mobile-logo'); 23 var companyName = mobileCarousel.querySelector('.js-testimonials-mobile-company'); 24 var companyAuthor = mobileCarousel.querySelector('.js-testimonials-mobile-author'); 25 26 if (!track || !container || slides.length === 0) return; 27 28 var currentIndex = 0; 29 var isAnimating = false; 30 var slideCount = slides.length; 31 var transitionDuration = 500; 32 var autoPlayInterval = null; 33 var slideWidth = 0; 34 35 // ÐаннÑе о компаниÑÑ 36 var companiesData = []; 37 for (var i = 0; i < slides.length; i++) { 38 companiesData.push({ 39 logo: slides[i].getAttribute('data-logo') || '', 40 company: slides[i].getAttribute('data-company') || '', 41 author: slides[i].getAttribute('data-author') || '' 42 }); 43 } 44 45 // УÑÑановиÑÑ ÑазмеÑÑ Ñлайдов 46 function setupSlides() { 47 // ÐолÑÑаем ÑиÑÐ¸Ð½Ñ ÐºÐ¾Ð½ÑейнеÑа 48 slideWidth = mobileCarousel.offsetWidth || 320; 49 50 if (slideWidth === 0) { 51 slideWidth = 320; 52 } 53 54 // УÑÑанавливаем ÑÑили конÑейнеÑа 55 container.style.width = slideWidth + 'px'; 56 container.style.overflow = 'hidden'; 57 58 // УÑÑановиÑÑ ÑиÑÐ¸Ð½Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñлайда 59 for (var i = 0; i < slides.length; i++) { 60 slides[i].style.width = slideWidth + 'px'; 61 slides[i].style.minWidth = slideWidth + 'px'; 62 } 63 64 // УÑÑановиÑÑ ÑиÑÐ¸Ð½Ñ ÑÑека 65 track.style.display = 'flex'; 66 track.style.width = (slideWidth * slideCount) + 'px'; 67 68 // ÐбновиÑÑ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ 69 updateCarousel(false); 70 } 71 72 // ÐбновиÑÑ Ð¾ÑобÑажение компании 73 function updateCompanyInfo() { 74 var data = companiesData[currentIndex]; 75 if (companyLogo && data && data.logo) { 76 companyLogo.src = data.logo; 77 companyLogo.alt = data.company || ''; 78 } 79 if (companyName && data) { 80 companyName.textContent = data.company || ''; 81 } 82 if (companyAuthor && data) { 83 companyAuthor.textContent = data.author || ''; 84 } 85 } 86 87 // ÐбновиÑÑ Ð¿Ð¾Ð·Ð¸ÑÐ¸Ñ ÐºÐ°ÑÑÑели 88 function updateCarousel(animate) { 89 if (animate !== false) { 90 track.style.transition = 'transform 0.5s ease'; 91 } else { 92 track.style.transition = 'none'; 93 } 94 var offset = -currentIndex * slideWidth; 95 track.style.transform = 'translateX(' + offset + 'px)'; 96 updateCompanyInfo(); 97 } 98 99 // СледÑÑÑий Ñлайд 100 function nextSlide() { 101 if (isAnimating) return; 102 isAnimating = true; 103 104 currentIndex++; 105 if (currentIndex >= slideCount) { 106 currentIndex = 0; 107 } 108 updateCarousel(true); 109 110 setTimeout(function() { 111 isAnimating = false; 112 }, transitionDuration); 113 } 114 115 // ÐÑедÑдÑÑий Ñлайд 116 function prevSlide() { 117 if (isAnimating) return; 118 isAnimating = true; 119 120 currentIndex--; 121 if (currentIndex < 0) { 122 currentIndex = slideCount - 1; 123 } 124 updateCarousel(true); 125 126 setTimeout(function() { 127 isAnimating = false; 128 }, transitionDuration); 129 } 130 131 // ÐбÑабоÑÑики кнопок 132 if (nextBtn) { 133 nextBtn.addEventListener('click', function(e) { 134 e.preventDefault(); 135 stopAutoPlay(); 136 nextSlide(); 137 }); 138 } 139 140 if (prevBtn) { 141 prevBtn.addEventListener('click', function(e) { 142 e.preventDefault(); 143 stopAutoPlay(); 144 prevSlide(); 145 }); 146 } 147 148 // Touch/Swipe 149 var touchStartX = 0; 150 var touchEndX = 0; 151 var swipeThreshold = 50; 152 153 track.addEventListener('touchstart', function(e) { 154 touchStartX = e.changedTouches[0].screenX; 155 stopAutoPlay(); 156 }, { passive: true }); 157 158 track.addEventListener('touchend', function(e) { 159 touchEndX = e.changedTouches[0].screenX; 160 var diff = touchStartX - touchEndX; 161 if (Math.abs(diff) > swipeThreshold) { 162 if (diff > 0) { 163 nextSlide(); 164 } else { 165 prevSlide(); 166 } 167 } 168 }, { passive: true }); 169 170 // ÐвÑовоÑпÑоизведение 171 function startAutoPlay() { 172 stopAutoPlay(); 173 autoPlayInterval = setInterval(function() { 174 if (!isAnimating) { 175 nextSlide(); 176 } 177 }, 5000); 178 } 179 180 function stopAutoPlay() { 181 if (autoPlayInterval) { 182 clearInterval(autoPlayInterval); 183 autoPlayInterval = null; 184 } 185 } 186 187 // ÐеÑеÑÑиÑаÑÑ Ð¿Ñи изменении ÑазмеÑа окна 188 var resizeTimer; 189 window.addEventListener('resize', function() { 190 clearTimeout(resizeTimer); 191 resizeTimer = setTimeout(function() { 192 setupSlides(); 193 }, 100); 194 }); 195 196 // ÐниÑиализаÑÐ¸Ñ 197 setupSlides(); 198 startAutoPlay(); 199 200 console.log('Mobile carousel initialized. Slides:', slideCount, 'Width:', slideWidth); 201 } 202 203 // ÐапÑÑк 204 if (document.readyState === 'loading') { 205 document.addEventListener('DOMContentLoaded', initMobileCarousel); 206 } else { 207 initMobileCarousel(); 208 } 209 210})();
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.