1document.addEventListener("DOMContentLoaded", function() { 2 var carousels = document.querySelectorAll(".bzkshop-carousel"); 3 for (var i = 0; i < carousels.length; i++) { 4 initCarousel(carousels[i]); 5 } 6}); 7 8function initCarousel(container) { 9 var list = container.querySelector(".bzkshop-list"); 10 var prev = container.querySelector(".bzkshop-carousel-prev"); 11 var next = container.querySelector(".bzkshop-carousel-next"); 12 if (!list || !prev || !next) return; 13 var origItems = list.querySelectorAll(".bzkshop-item"); 14 var origCount = origItems.length; 15 if (origCount === 0) return; 16 17 // Forcer les styles critiques via JS (safety net si CSS pas chargé) 18 list.style.setProperty("display", "flex", "important"); 19 list.style.setProperty("flex-wrap", "nowrap", "important"); 20 list.style.setProperty("flex-direction", "row", "important"); 21 list.style.setProperty("overflow-x", "scroll", "important"); 22 list.style.setProperty("overflow-y", "hidden", "important"); 23 list.style.setProperty("-ms-overflow-style", "none", "important"); 24 list.style.setProperty("scrollbar-width", "none", "important"); 25 26 // Cloner tous les items pour boucle infinie 27 for (var i = 0; i < origCount; i++) { 28 var clone = origItems[i].cloneNode(true); 29 clone.setAttribute("data-bzk-clone", "1"); 30 list.appendChild(clone); 31 } 32 var items = list.querySelectorAll(".bzkshop-item"); 33 34 function getItemMargin() { 35 var style = window.getComputedStyle(items[0]); 36 var ml = parseFloat(style.marginLeft); 37 var mr = parseFloat(style.marginRight); 38 // parseFloat("auto") = NaN : fallback 8px par côté 39 if (isNaN(ml)) ml = 8; 40 if (isNaN(mr)) mr = 8; 41 return ml + mr; 42 } 43 44 function sizeItems() { 45 var margin = getItemMargin(); 46 var containerW = list.clientWidth; 47 48 // Utiliser data-per-view si dispo, sinon auto-detect via min-width CSS 49 var perView = parseInt(container.getAttribute("data-per-view")) || 0; 50 // Mobile : forcer per_view=1 (box est déjà 1) 51 if (perView > 1 && window.innerWidth <= 768) { 52 perView = 1; 53 } 54 if (perView <= 0) { 55 for (var i = 0; i < items.length; i++) { 56 items[i].style.width = ""; 57 items[i].style.minWidth = ""; 58 } 59 var style = window.getComputedStyle(items[0]); 60 var minW = parseFloat(style.minWidth) || items[0].offsetWidth; 61 perView = Math.max(1, Math.floor(containerW / (minW + margin))); 62 } 63 64 var widthVal = "calc(100% / " + perView + " - " + margin + "px)"; 65 for (var i = 0; i < items.length; i++) { 66 items[i].style.setProperty("width", widthVal, "important"); 67 items[i].style.setProperty("max-width", widthVal, "important"); 68 items[i].style.setProperty("min-width", "0", "important"); 69 items[i].style.setProperty("flex", "0 0 auto", "important"); 70 items[i].style.setProperty("float", "none", "important"); 71 } 72 return { perView: perView, itemWidth: items[0].offsetWidth + margin }; 73 } 74 75 var info = sizeItems(); 76 77 // Si clientWidth = 0, le layout n'est pas prêt, réessayer 78 if (info.itemWidth <= 0) { 79 requestAnimationFrame(function() { 80 info = sizeItems(); 81 }); 82 } 83 84 function getOrigWidth() { 85 return origCount * info.itemWidth; 86 } 87 88 function snapTo(scrollPos) { 89 var iw = info.itemWidth; 90 if (iw <= 0) return 0; 91 return Math.round(scrollPos / iw) * iw; 92 } 93 94 // Reset instantané (bypass scroll-behavior: smooth du CSS) 95 function instantScroll(pos) { 96 list.style.scrollBehavior = "auto"; 97 list.scrollLeft = pos; 98 // Force reflow pour appliquer avant de remettre smooth 99 list.offsetLeft; 100 list.style.scrollBehavior = ""; 101 } 102 103 // Reset silencieux si on est dans la zone clone 104 var scrollTimer = null; 105 function checkLoop() { 106 var totalOrig = getOrigWidth(); 107 if (totalOrig <= 0) return; 108 if (list.scrollLeft >= totalOrig) { 109 instantScroll(list.scrollLeft - totalOrig); 110 } 111 } 112 113 // Flèches 114 prev.addEventListener("click", function() { 115 // Recalculer si besoin (items pas encore dimensionnés) 116 if (info.itemWidth <= 0) info = sizeItems();
117 if (Math.round(list.scrollLeft) <= 0) { 118 // Au début : saut invisible vers la zone clone, puis scroll arrière 119 instantScroll(getOrigWidth()); 120 } 121 var target = snapTo(list.scrollLeft - info.perView * info.itemWidth); 122 list.scrollTo({ left: Math.max(0, target), behavior: "smooth" }); 123 }); 124 125 next.addEventListener("click", function() { 126 // Recalculer si besoin 127 if (info.itemWidth <= 0) info = sizeItems(); 128 var target = snapTo(list.scrollLeft + info.perView * info.itemWidth); 129 list.scrollTo({ left: target, behavior: "smooth" }); 130 }); 131 132 // Détection fin de scroll : reset vers la zone originale 133 list.addEventListener("scroll", function() { 134 clearTimeout(scrollTimer); 135 scrollTimer = setTimeout(checkLoop, 150); 136 }); 137 138 // Mouse drag 139 var isDragging = false; 140 var startX = 0; 141 var startScroll = 0; 142 var hasMoved = false; 143 144 list.addEventListener("mousedown", function(e) { 145 isDragging = true; 146 hasMoved = false; 147 startX = e.pageX; 148 startScroll = list.scrollLeft; 149 list.classList.add("bzk-dragging"); 150 e.preventDefault(); 151 }); 152 153 document.addEventListener("mousemove", function(e) { 154 if (!isDragging) return; 155 var dx = e.pageX - startX; 156 if (Math.abs(dx) > 3) hasMoved = true; 157 list.scrollLeft = startScroll - dx; 158 }); 159 160 document.addEventListener("mouseup", function() { 161 if (!isDragging) return; 162 isDragging = false; 163 list.classList.remove("bzk-dragging"); 164 var target = snapTo(list.scrollLeft); 165 list.scrollTo({ left: target, behavior: "smooth" }); 166 }); 167 168 // Empêcher le clic sur les liens si on a draggé 169 list.addEventListener("click", function(e) { 170 if (hasMoved) { 171 e.preventDefault(); 172 e.stopPropagation(); 173 hasMoved = false; 174 } 175 }, true); 176 177 // Touch drag 178 list.addEventListener("touchstart", function(e) { 179 isDragging = true; 180 hasMoved = false; 181 startX = e.touches[0].pageX; 182 startScroll = list.scrollLeft; 183 list.classList.add("bzk-dragging"); 184 }, { passive: true }); 185 186 list.addEventListener("touchmove", function(e) { 187 if (!isDragging) return; 188 var dx = e.touches[0].pageX - startX; 189 if (Math.abs(dx) > 3) hasMoved = true; 190 list.scrollLeft = startScroll - dx; 191 }, { passive: true }); 192 193 list.addEventListener("touchend", function() { 194 if (!isDragging) return; 195 isDragging = false; 196 list.classList.remove("bzk-dragging"); 197 var target = snapTo(list.scrollLeft); 198 list.scrollTo({ left: target, behavior: "smooth" }); 199 }); 200 201 // Resize 202 window.addEventListener("resize", function() { 203 info = sizeItems(); 204 instantScroll(snapTo(list.scrollLeft)); 205 }); 206}
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.