1/* ========================================================= 2 EXCLUSIF ââ¬â Galerie Slider 3 Fichier : /docs/JS/exclusif-galerie-slider.js 4 5 - .module-galerie.type-1 => cartes premium 6 - .module-galerie.type-2 => roll hover premium 7 - compteur lisible 8 - patch SAFE retour arrière navigateur 9 ========================================================= */ 10(function () { 11 'use strict'; 12 13 function qsa(root, sel) { 14 return Array.prototype.slice.call(root.querySelectorAll(sel)); 15 } 16 17 function getItemsForModule(module) { 18 if (module.classList.contains('type-1')) { 19 var cel1 = module.querySelector('.cel1'); 20 if (!cel1) return { container: null, items: [] }; 21 return { 22 container: cel1, 23 items: qsa(cel1, ':scope > .col') 24 }; 25 } 26 27 if (module.classList.contains('type-2')) { 28 var cel1safe = module.querySelector('.cel1safe'); 29 if (!cel1safe) return { container: null, items: [] }; 30 return { 31 container: cel1safe, 32 items: qsa(cel1safe, ':scope > .column') 33 }; 34 } 35 36 return { container: null, items: [] }; 37 } 38 39 function getCols() { 40 var w = window.innerWidth || document.documentElement.clientWidth || 1200; 41 if (w <= 520) return 1; 42 if (w <= 700) return 2; 43 if (w <= 1100) return 3; 44 return 5; 45 } 46 47 function chunk(items, size) { 48 var pages = []; 49 for (var i = 0; i < items.length; i += size) { 50 pages.push(items.slice(i, i + size)); 51 } 52 return pages; 53 } 54 55 function buildNavButton(type, label) { 56 var btn = document.createElement('button'); 57 btn.type = 'button'; 58 btn.className = 'xg-nav xg-nav--' + type; 59 btn.setAttribute('aria-label', label); 60 return btn; 61 } 62 63 function destroySlider(module) { 64 var originalContainer = module.__xgOriginalContainer; 65 var movedItems = module.__xgMovedItems; 66 67 var oldShell = module.querySelector('.xg-slider-shell'); 68 if (oldShell) oldShell.remove(); 69 70 if (originalContainer && movedItems && movedItems.length) { 71 movedItems.forEach(function (item) { 72 originalContainer.appendChild(item); 73 }); 74 } 75 76 module.classList.remove('xg-slider-ready'); 77 module.__xgBuilt = false; 78 module.__xgCurrentPage = 0; 79 module.__xgTrack = null; 80 module.__xgPrev = null; 81 module.__xgNext = null; 82 module.__xgCounterCurrent = null; 83 module.__xgCounterTotal = null; 84 module.__xgPagesCount = 0; 85 } 86 87 function buildSlider(module) { 88 var data = getItemsForModule(module); 89 var container = data.container; 90 var items = data.items; 91 92 if (!container) { 93 module.classList.remove('xg-slider-ready'); 94 return; 95 } 96 97 if (items.length <= 5) { 98 module.classList.remove('xg-slider-ready'); 99 return; 100 } 101 102 module.__xgOriginalContainer = container; 103 module.__xgMovedItems = items.slice(); 104 105 var cols = getCols(); 106 module.style.setProperty('--xg-cols', String(cols)); 107 108 var pages = chunk(items, cols); 109 if (pages.length <= 1) { 110 module.classList.remove('xg-slider-ready'); 111 return; 112 } 113 114 var shell = document.createElement('div'); 115 shell.className = 'xg-slider-shell'; 116 117 var viewport = document.createElement('div'); 118 viewport.className = 'xg-slider-viewport'; 119 120 var track = document.createElement('div'); 121 track.className = 'xg-slider-track'; 122 123 pages.forEach(function (pageItems) { 124 var slide = document.createElement('div'); 125 slide.className = 'xg-slide'; 126 127 var grid = document.createElement('div'); 128 grid.className = 'xg-slide-grid'; 129 130 pageItems.forEach(function (item) { 131 grid.appendChild(item); 132 }); 133 134 slide.appendChild(grid); 135 track.appendChild(slide); 136 }); 137 138 viewport.appendChild(track); 139 140 var prev = buildNavButton('prev', 'Galeries précédentes'); 141 var next = buildNavButton('next', 'Galeries suivantes'); 142 143 var meta = document.createElement('div'); 144 meta.className = 'xg-slider-meta'; 145 146 var counter = document.createElement('div'); 147 counter.className = 'xg-counter'; 148 counter.setAttribute('aria-live', 'polite'); 149 150 var current = document.createElement('span'); 151 current.className = 'xg-counter-current'; 152 current.textContent = '1'; 153 154 var sep = document.createElement('span'); 155 sep.className = 'xg-counter-sep'; 156 sep.textContent = '/'; 157 158 var total = document.createElement('span'); 159 total.className = 'xg-counter-total'; 160 total.textContent = String(pages.length); 161 162 counter.appendChild(current); 163 counter.appendChild(sep); 164 counter.appendChild(total); 165 meta.appendChild(counter); 166 167 shell.appendChild(prev); 168 shell.appendChild(viewport); 169 shell.appendChild(next); 170 shell.appendChild(meta); 171 172 qsa(container, ':scope > .clear, :scope > .clearimportant, :scope > .clear.clearimportant').forEach(function (node) { 173 node.remove(); 174 }); 175 176 container.appendChild(shell); 177 178 module.classList.add('xg-slider-ready'); 179 180 module.__xgBuilt = true; 181 module.__xgTrack = track; 182 module.__xgPrev = prev; 183 module.__xgNext = next; 184 module.__xgCounterCurrent = current; 185 module.__xgCounterTotal = total; 186 module.__xgPagesCount = pages.length; 187 module.__xgCurrentPage = 0; 188 189 function render() { 190 var page = module.__xgCurrentPage || 0; 191 track.style.transform = 'translateX(' + (-page * 100) + '%)'; 192 193 prev.disabled = page <= 0; 194 next.disabled = page >= module.__xgPagesCount - 1; 195 196 if (module.__xgCounterCurrent) { 197 module.__xgCounterCurrent.textContent = String(page + 1); 198 } 199 if (module.__xgCounterTotal) { 200 module.__xgCounterTotal.textContent = String(module.__xgPagesCount); 201 } 202 } 203 204 prev.addEventListener('click', function () { 205 if (module.__xgCurrentPage > 0) { 206 module.__xgCurrentPage -= 1; 207 render(); 208 } 209 }); 210 211 next.addEventListener('click', function () { 212 if (module.__xgCurrentPage < module.__xgPagesCount - 1) { 213 module.__xgCurrentPage += 1; 214 render(); 215 } 216 }); 217 218 render(); 219 } 220 221 function rebuildModule(module) { 222 destroySlider(module); 223 buildSlider(module); 224 } 225
226 function init() { 227 var modules = qsa(document, '.module-galerie.type-1, .module-galerie.type-2'); 228 modules.forEach(function (module) { 229 rebuildModule(module); 230 }); 231 } 232 233 var resizeTimer = null; 234 window.addEventListener('resize', function () { 235 window.clearTimeout(resizeTimer); 236 resizeTimer = window.setTimeout(function () { 237 init(); 238 }, 180); 239 }); 240 241 /* ========================================================= 242 PATCH SAFE ââ¬â retour arrière navigateur 243 On ne masque rien, on ne reconstruit pas agressivement. 244 On recale juste le track sans animation au pageshow. 245 ========================================================= */ 246 window.addEventListener('pageshow', function () { 247 var modules = qsa(document, '.module-galerie.type-1, .module-galerie.type-2'); 248 249 modules.forEach(function (module) { 250 var track = module.__xgTrack; 251 if (!track) return; 252 253 var oldTransition = track.style.transition; 254 track.style.transition = 'none'; 255 256 var page = module.__xgCurrentPage || 0; 257 track.style.transform = 'translateX(' + (-page * 100) + '%)'; 258 259 void track.offsetHeight; 260 261 track.style.transition = oldTransition || ''; 262 }); 263 }); 264 265 if (document.readyState === 'loading') { 266 document.addEventListener('DOMContentLoaded', init); 267 } else { 268 init(); 269 } 270})();
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.