PageSourceSearch

https://parler-de-sa-vie.net/user/themes/goldman/js/main.js?g-6bcd3335

js parler-de-sa-vie.net collected 2026-09-25 00:11:12 UTC 13,928 bytes, 380 lines download raw bytes

1$(document).ready(function(){
2    console.log('main.js OK')
3    // $('.order').on('click', function () {
4    //     // console.log('clicked OK');
5    //     // console.log('clicked : ', $(this).attr("data-set-order"));
6    //     var value = $(this).attr("data-set-order");
7    //     window.articleOrder = value;
8    //     console.log('var articleOrder : ', window.articleOrder);
9    // })
10//////////////////////////////////////// ARTICLE LINKS ON BUTTON  ////////////////////////////////////////
11
12    $('[clickable],[data-clickable]').click(function(){
13        var link = $(this).find('a:not([data-clickable-notfollow])').attr('href');
14        var link = link ? link : $(this).attr('data-clickable');
15        if(link){ location.href = link; }
16        return false;
17    });
18
19    $('a[data-clickable-notfollow]').click(function(e){
20        e.preventDefault();
21        location.href = $(this).attr('href');
22        return false;
23    });
24
25
26////// NAVIGATION TOGGLE SCROLL  //////////////////////////////////////////////////////
27
28    var scrollTop = 0;
29    function scrolledNav(){
30        scrollTop = $(window).scrollTop();
31        $('.counter').html(scrollTop);
32
33        if (scrollTop >= 100) {
34            $('#main-header').addClass('scrolled-nav');
35        } else if (scrollTop < 100) {
36            $('#main-header').removeClass('scrolled-nav');
37        }
38    };
39
40    $(window).scroll(function(){
41        if($('#navigation').hasClass('nav-is-open')) {
42            $('#main-header').removeClass('scrolled-nav');
43        } else {
44            scrolledNav();
45        }
46    });
47
48
49
50////// SMOOTH SCROLL  //////////////////////////////////////////////////////
51
52    // $("a").on('click', function(event) {
53    //     if(this.hash == '#') {
54    //         preventDefault();
55    //     }
56    // }
57    //
58    // function preventDefault() {
59    //     event.preventDefault();
60    // };
61
62    // Add smooth scrolling to all links
63    // $("a:not(.read-more)[href^='#']").on('click', function(event) {
64    //     if (this.hash !== "#") {
65    //         // Prevent default anchor click behavior
66    //         event.preventDefault();
67    //
68    //         // Store hash
69    //         var hash = this.hash;
70    //         var dataTop = $(this).attr('data-top');
71    //         var moveTop = dataTop ? dataTop : 0;
72    //
73    //         // Using jQuery's animate() method to add smooth page scroll
74    //         // The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
75    //         $('html, body').stop().animate({
76    //             scrollTop: $(hash).offset().top
77    //         }, 200, function(){
78    //
79    //
80    //         // Add hash (#) to URL when done scrolling (default click behavior)
81    //         window.location.hash = hash;
82    //         });
83    //     } // End if
84    // });
85
86
87////// NAVIGATION TOGGLE OPEN  //////////////////////////////////////////////////////
88
89    // Global navigation
90    $('.navigation-main > div').on('click', function () {
91        var nav = $('#navigation');
92
93        nav.toggleClass('nav-is-open');
94
95        if(nav.hasClass('nav-is-open')) {
96            $('#main-header').removeClass('scrolled-nav');
97        } else {
98            scrolledNav();
99        }
100    });
101
102    // Sous-menus : gérés uniquement par le chevron .submenu-toggle (voir le script
103    // en bas de base.html.twig) qui bascule .is-open → accordéon mobile + volet
104    // desktop en CSS. `has-submenu` est posé côté template (navigation.html.twig).
105    //
106    // L'ancien toggle sur le <li> entier a été RETIRÉ : il captait aussi les clics
107    // des liens (parent ET enfants du sous-menu par bubbling), posait une classe
108    // morte `submenu-is-open` (n'ouvre rien : le CSS ne déplie que via .is-open) et
109    // surtout `active` → le lien parent virait au jaune « comme activé », en plus
110    // d'un clic parasite. D'où l'impression qu'il fallait 2-3 clics pour atteindre
111    // un sous-item. Ne pas réintroduire ce handler.
112
113
114
115////// CHANGE TAB  //////////////////////////////////////////////////////
116
117    (function ($) {
118        function findTargetId($li) {
119            var id = $li.data('id');
120            if (id && document.getElementById(id)) return id;
121            var $a = $li.find('> .tab-title a[href^="#"], > h2 a[href^="#"], > a[href^="#"]').first();
122            if ($a.length) {
123                var h = $a.attr('href').replace(/^.*#/, '');
124                if (h && document.getElementById(h)) return h;
125            }
126            return null;
127        }
128
129        function syncActive($tabs) {
130            var $lis = $tabs.find('ul.tab > li');
131            var $allPanels = $tabs.find('.tab-content');
132
133            if ($lis.length === 1) {
134                var $li = $lis.eq(0);
135                $lis.removeClass('active');
136                $allPanels.removeClass('active');
137
138                $li.addClass('active is-single').attr('aria-disabled', 'true');
139
140                var $inside = $li.children('.tab-content');
141                if ($inside.length) $inside.addClass('active');
142                else {
143                    var id = findTargetId($li);
144                    if (id) $('#' + id).addClass('active');
145                }
146                $li.find('.tab-title, h2, a').attr('tabindex', '-1');
147                return;
148            }
149            if (!$lis.filter('.active').length) {
150                // Rien d'actif, rien à synchroniser.
151                return;
152            }
153
154            $allPanels.removeClass('active');
155            var $active = $lis.filter('.active').eq(0);
156            var $inside = $active.children('.tab-content');
157            if ($inside.length) { $inside.addClass('active'); return; }
158            var id = findTargetId($active);
159            if (id) { $('#' + id).addClass('active'); return; }
160        }
161
162        function closeLi($li) {
163            var $tabs = $li.closest('.tabs');
164            $li.removeClass('active');
165            $li.children('.tab-content.active').removeClass('active');
166            var id = findTargetId($li);
167            if (id) $('#' + id).removeClass('active');
168        }
169
170        // Accordéon vertical (contenu enfant du <li>) : à l'ouverture, la
171        // fermeture de l'onglet précédent décale la page ; on ramène donc
172        // l'en-tête de l'onglet ouvert en haut de l'écran.
173        function scrollTabIntoView($li) {
174            var offset = 24;
175            var header = document.getElementById('main-header');
176            if (header && getComputedStyle(header).position === 'fixed') {
177                offset = header.offsetHeight + 12;
178            }
179            var top = $li[0].getBoundingClientRect().top + window.pageYOffset - offset;
180            window.scrollTo({ top: Math.max(0, top), behavior: 'smooth' });
181        }
182
183        function changeTab($li) {
184            var $tabs = $li.closest('.tabs');
185            var $lis = $tabs.find('ul.tab > li');
186
187            if ($li.is('.is-single') || $li.is('[aria-disabled="true"]')) return;
188
189            if ($li.hasClass('active')) {
190                closeLi($li);
191                return;
192            }
193            $lis.removeClass('active');
194            $tabs.find('.tab-content.active').removeClass('active');
195
196            $li.addClass('active');
197
198            var $inside = $li.children('.tab-content');
199            if ($inside.length) { $inside.addClass('active'); scrollTabIntoView($li); return; }
200
201            var id = findTargetId($li);
202            if (id) { $('#' + id).addClass('active'); return; }
203            $li.removeClass('active');
204        }
205
206        // Ouvre l'onglet correspondant à un hash (ex. /biographie#racines),
207        // comme si on cliquait dessus. S'appuie sur data-tab-slug.
208        function openTabBySlug(hash) {
209            var slug = String(hash || '').replace(/^#/, '').toLowerCase();
210            if (!slug) return;
211            var $li = $('.tabs ul.tab > li[data-tab-slug="' + slug + '"]').first();
212            if (!$li.length) return;
213            if (!$li.hasClass('active')) changeTab($li); // ouvre + scrolle
214            else scrollTabIntoView($li);                 // déjà ouverte -> on recadre
215        }
216
217        // Ouvre la popup d'un récit de concert via un hash date (ex. /concerts/...#1998-04-25),
218        // comme si on cliquait sur la date commentée. S'appuie sur data-recit-date.
219        function openRecitByDate(hash) {
220            var date = String(hash || '').replace(/^#/, '');
221            if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) return;
222            var btn = document.querySelector('.btn-recit-full[data-recit-date="' + date + '"]');
223            if (!btn) return;
224            btn.scrollIntoView({ block: 'center' });
225            btn.click(); // modal.js délègue l'ouverture sur [data-modal-open]
226        }
227
228        function handleHash() {
229            openTabBySlug(window.location.hash);
230            openRecitByDate(window.location.hash);
231        }
232
233        $(function () {
234            $('.tabs').each(function () { syncActive($(this)); });
235            handleHash();
236        });
237        // Rejeu après chargement complet (images comprises) pour fiabiliser recadrage/p
237opup.
238        $(window).on('load', handleHash);
239        $(window).on('hashchange', handleHash);
240        // Ignore les clics dans le contenu, dans les boutons/modales, etc.
241        $(document).on('click', '.tabs ul.tab > li', function (e) {
242            var $t = $(e.target);
243
244            // 1) Si le clic vient d'un bouton d'ouverture de modale ou d'une modale/fallback, on ne touche pas aux tabs
245            if ($t.closest('[data-modal-open], .modal, .modal-fallback, .modal-fallback-dialog').length) return;
246
247            // 2) Si le clic est dans la zone de contenu de l'onglet (pas sur le header), on ne change pas d'onglet
248            if ($t.closest('.tab-content').length) return;
249
250            // 3) Gestion classique du header d'onglet
251            if (e.target.closest('a[href^="#"]')) e.preventDefault();
252            e.preventDefault();
253            changeTab($(this));
254        });
255
256        $(document).on('click', '.tabs ul.tab > li .tab-title a[href^="#"]', function (e) {
257            e.preventDefault();
258        });
259    })(jQuery);
260
261////// TOGGLE READ-MORE HEADER SIDE INFOS  /////////////////////////////
262
263    $('.read-more').on('click', function () {
264        event.preventDefault();
265        $(this).parent().toggleClass('read-more-is-active');
266    });
267
268    $('.txt-content-wrapper .icon.icon-simple-cross').on('click', function () {
269        $(this).parent().parent().toggleClass('read-more-is-active');
270    });
271
272
273////// TOGGLE DROPDOWN IS OPEN  /////////////////////////////
274    $('.dropdown-container .btn.btn-close').on('click', function () {
275        $(this).closest( "section" ).toggleClass('dropdown-is-open');
276    });
277
278////// JS SEE MORE  /////////////////////////////
279    $('.js-see-more').each(function () {
280        const btn = $(this);
281        const container = btn.closest('.js-see-more-container');
282        const targetSelector = btn.data('target');
283        const initial = parseInt(btn.data('initial-item'), 10) || 9;
284        const increment = parseInt(btn.data('increment'), 10) || initial;
285        const seeAll = btn.data('see-all') === true || btn.data('see-all') === 'true';
286
287        const items = container.find(targetSelector);
288        let visibleCount = initial;
289        let reachedEnd = false;
290
291        const updateItems = () => {
292            items.hide();
293            items.slice(0, visibleCount).fadeIn();
294
295            if (visibleCount >= items.length) {
296                reachedEnd = true;
297                btn.addClass('expanded').find('span').text('Voir moins');
298            } else {
299                reachedEnd = false;
300                btn.removeClass('expanded').find('span').text('Voir plus');
301            }
302        };
303
304        updateItems();
305
306        btn.on('click', function (e) {
307            e.preventDefault();
308
309            if (!seeAll) {
310                if (reachedEnd) {
311                    visibleCount = initial;
312                } else {
313                    visibleCount = Math.min(visibleCount + increment, items.length);
314                }
315            } else {
316                visibleCount = btn.hasClass('expanded') ? initial : items.length;
317            }
318
319            updateItems();
320        });
321    });
322
323
324
325////// SWIPER  /////////////////////////////
326//     var swiper1 = new Swiper('.swiper-name-1.swiper-container', {
327//         // loop: true,
328//         speed: 500,
329//         keyboard: true,
330//         grabCursor: true,
331//         slidesPerView: 'auto',
332//         centeredSlides: true,
333//         spaceBetween: 30,
334//         observer: true,
335//         observeParents: true,
336//         pagination: {
337//             el: '.swiper-name-1 .swiper-pagination',
338//             type: 'bullets',
339//             dynamicBullets: true,
340//             clickable: true,
341//         }
342//     });
343//
344//     var swiper2 = new Swiper('.swiper-name-2.swiper-container', {
345//         // loop: true,
346//         speed: 500,
347//         keyboard: true,
348//         grabCursor: true,
349//         slidesPerView: 'auto',
350//         centeredSlides: true,
351//         spaceBetween: 30,
352//         observer: true,
353//         observeParents: true,
354//         pagination: {
355//             el: '.swiper-name-2 .swiper-pagination',
356//             type: 'bullets',
357//             dynamicBullets: true,
358//             clickable: true,
359//         }
360//     });
361//
362//     var swiper3 = new Swiper('.swiper-name-3.swiper-container', {
363//         // loop: true,
364//         speed: 500,
365//         keyboard: true,
366//         grabCursor: true,
367//         slidesPerView: 'auto',
368//         centeredSlides: true,
369//         spaceBetween: 30,
370//         observer: true,
371//         observeParents: true,
372//         pagination: {
373//             el: '.swiper-name-3 .swiper-pagination',
374//             type: 'bullets',
375//             dynamicBullets: true,
376//             clickable: true,
377//         }
378//     });
379
380});

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.