1const sections = document.querySelectorAll('.gallery'); 2 3window.addEventListener('load', function () { 4 sections.forEach((section, index) => { 5 const images = section.querySelectorAll('.splide__slide a'); 6 7 images.forEach((image) => { 8 image.setAttribute('data-fslightbox', `gallery-${index}`); 9 }); 10 }); 11}); 12 13// SPLIDE SLIDER FUNC 14document.addEventListener('DOMContentLoaded', () => { 15 sections.forEach(function (slider) { 16 /** 17 * Common Configuration for Splide 18 * * Accessibility Fix: 19 * By default, Splide adds 'role="group"' and 'aria-roledescription="slide"'. 20 * In some environments, this conflicts with <li> semantics or causes Axe errors 21 * if the parent <ul> doesn't match the expected ARIA pattern perfectly. 22 */ 23 const commonOptions = { 24 role: '', 25 i18n: { 26 slideX: '', 27 }, 28 slideFocus: false, 29 }; 30 31 // Initialize Main Slider (The large image view) 32 const mainElement = slider.querySelector('.thumbnail-navigation'); 33 34 if (!mainElement) return; 35 36 let main = new Splide(mainElement, { 37 ...commonOptions, 38 type: 'fade', 39 rewind: true, 40 pagination: false, 41 arrows: false, 42 }); 43 44 const thumbElement = slider.querySelector('.thumbnail-carousel'); 45 46 if (!thumbElement) return; 47 48 let thumbnails = new Splide(thumbElement, { 49 ...commonOptions, 50 fixedWidth: 100, 51 fixedHeight: 60, 52 gap: 5, 53 rewind: true, 54 focus: 'center', 55 pagination: false, 56 isNavigation: true, 57 }); 58 59 // Sync sliders so they move together 60 main.sync(thumbnails); 61 main.mount(); 62 thumbnails.mount(); 63 64 /** 65 * Gallery Counter Logic 66 * Updates a text element (e.g., "1/15") when the slide changes. 67 */ 68 const slides = thumbElement.querySelectorAll('.splide__slide'); 69 const totalImages = slides.length; 70 const counterElement = slider.querySelector('.counter'); 71 72 // Update counter text on slide movement 73 main.on('moved', function (newIndex) { 74 if (counterElement) { 75 counterElement.innerHTML = `${newIndex + 1}/${totalImages}`; 76 } 77 }); 78 79 // Set initial counter state 80 if (counterElement) { 81 counterElement.innerHTML = `1/${totalImages}`; 82 } 83 84 /** 85 * FINAL ACCESSIBILITY CLEANUP (Axe DevTools Fix) 86 * * Even with role: "" Splide might inject internal ARIA attributes during the mount process. 87 * This helper removes specific attributes from every slide 88 * to ensure the <li> elements remain semantically "clean" for Axe. 89 */ 90 const cleanA11y = (splideInstance) => { 91 // Use Splide's internal components to loop through all slides efficiently 92 splideInstance.Components.Slides.forEach((slide) => { 93 if (slide.slide) { 94 // Remove attributes that cause "prohibited for an element's role" errors 95 slide.slide.removeAttribute('role'); 96 slide.slide.removeAttribute('aria-roledescription'); 97 slide.slide.removeAttribute('aria-label'); 98 } 99 }); 100 }; 101 102 // Execute cleanup immediately after mounting (more reliable than setTimeout) 103 cleanA11y(main); 104 cleanA11y(thumbnails); 105 }); 106});
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.