/* Lightbox: rüstet eine Bildergalerie ([data-lightbox-gallery]) von normalen Bildlinks auf eine Großansicht im Overlay um. Ohne JS bleibt jedes Vorschaubild ein Link auf die größte Variante der Datei — der Klick führt dann einfach zum Bild, nichts ist kaputt oder tot. Bewusst generisch gehalten (keine „veranstaltung"-Bezüge, Hooks nur über data-lightbox-*), damit eine zweite Galerie auf der Seite dieselbe Datei nutzen kann — dasselbe Prinzip wie beim generischen carousel.js. Das Overlay-Markup liefert PHP und ist `hidden`, bis JS es übernimmt (wie die Steuerung des Stadionzeitungs-Viewers). Die Großansicht erbt ihr srcset vom angeklickten Vorschaubild: so lädt ein Handy die kleine Variante und es gibt nur EINE Bildliste im Markup. */ (function () { 'use strict'; function initGallery(root) { var links = Array.prototype.slice.call(root.querySelectorAll('[data-lightbox]')); var dialog = root.querySelector('[data-lightbox-dialog]'); if (!dialog || links.length === 0) { return; } var image = dialog.querySelector('[data-lightbox-img]'); var counter = dialog.querySelector('[data-lightbox-current]'); var closeBtn = dialog.querySelector('[data-lightbox-close]'); var prevBtn = dialog.querySelector('[data-lightbox-prev]'); var nextBtn = dialog.querySelector('[data-lightbox-next]'); if (!image || !closeBtn) { return; } var index = 0; var isOpen = false; function show(i) { index = Math.max(0, Math.min(links.length - 1, i)); var thumb = links[index].querySelector('img'); image.src = links[index].getAttribute('href'); image.srcset = thumb ? thumb.getAttribute('srcset') || '' : ''; image.alt = thumb ? thumb.getAttribute('alt') || '' : ''; if (counter) { counter.textContent = String(index + 1); } if (prevBtn) { prevBtn.disabled = index === 0; } if (nextBtn) { nextBtn.disabled = index === links.length - 1; } // Am ersten/letzten Bild wird der gerade fokussierte Knopf disabled // und der Fokus fiele auf — dann griffe die Fokusfalle unten // nicht mehr und Tab liefe hinter das Overlay. if (document.activeElement && document.activeElement.disabled) { closeBtn.focus(); } } function onKeydown(event) { if (event.key === 'Escape') { event.preventDefault(); hide(); return; } if (event.key === 'ArrowLeft') { event.preventDefault(); show(index - 1); return; } if (event.key === 'ArrowRight') { event.preventDefault(); show(index + 1); return; } if (event.key !== 'Tab') { return; } // Fokusfalle: im Overlay sind nur diese Knöpfe erreichbar. var focusable = [prevBtn, nextBtn, closeBtn].filter(function (btn) { return btn && !btn.disabled; }); var first = focusable[0]; var last = focusable[focusable.length - 1]; if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); } else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); } } function reveal(i) { show(i); dialog.hidden = false; // Hintergrund festhalten, sonst scrollt die Seite unter dem Overlay // weg (gleiches Muster wie body.nav-open beim Burger-Menü). document.body.classList.add('lightbox-open'); document.addEventListener('keydown', onKeydown); isOpen = true; closeBtn.focus(); } function hide() { if (!isOpen) { return; } dialog.hidden = true; document.body.classList.remove('lightbox-open'); document.removeEventListener('keydown', onKeydown); isOpen = false; // Fokus zurück auf das ZULETZT gezeigte Vorschaubild, nicht auf das // zuerst angeklickte: nach mehrmals Weiter ist das die Stelle, an // der man im Raster gerade steht. links[index].focus(); } links.forEach(function (link, i) { link.addEventListener('click', function (event) { event.preventDefault(); reveal(i); }); }); if (prevBtn) { prevBtn.addEventListener('click', function () { show(index - 1); }); } if (nextBtn) { nextBtn.addEventListener('click', function () { show(index + 1); }); } closeBtn.addEventListener('click', hide); dialog.addEventListener('click', function (event) { // Klick auf die Fläche neben dem Bild schließt; Klicks auf Bild und // Knöpfe nicht. if (event.target === dialog) { hide(); } }); root.classList.add('is-enhanced'); } Array.prototype.slice.call(document.querySelectorAll('[data-lightbox-gallery]')).forEach(initGallery); })();