PageSourceSearch

https://www.exclusif.re/docs/JS/exclusif-galerie-slider.js?v=1773749001

js exclusif.re collected 2026-10-02 22:10:12 UTC 7,527 bytes, 270 lines download raw bytes

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.