Files
KantSites/public/assets/lightbox.js
T
kantarciandClaude Opus 5 de1e66350b
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s
Knopf nach oben, Bildbetrachter, Rechtszeile als Baustein (Schema v19)
Der Knopf "nach oben" ist ein Anker, kein Skript: er springt an den
Seitenanfang, eingeblendet ueber eine Scroll-Zeitachse. Abschaltbar und
vollstaendig einstellbar - Seite, Form, Groesse, Farben, Schwelle,
Beschriftung.

Bilder lassen sich vergroessern, je Bild waehlbar (nichts / vergroessern
/ Adresse), Galerien mit einem Schalter. Grundlage ist ein gewoehnlicher
Verweis auf die grosse Fassung: ohne JavaScript oeffnet er das Bild, mit
JavaScript einen dialog-Betrachter mit Blaettern, Escape und Pfeiltasten.
Das Skript laedt nur, wo es etwas zu tun hat.

Die Rechtszeile wird ein Baustein und steht damit im Fussbereich statt
als heller Streifen darunter. Die eingebaute Leiste erscheint nur noch,
wenn die Seite den Baustein nicht enthaelt.

Dabei gefunden: zwei Stylesheet-Regeln griffen seit drei
Veroeffentlichungen nicht mehr. Beim Entfernen alter Regeln waren
Selektorreste stehen geblieben, und CSS nimmt dann die naechste Regel
mit - betroffen waren der Einwilligungsdialog und die Rechtszeile. Ein
Test prueft jetzt jede CSS-Datei auf abgebrochene Selektoren.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 19:35:43 +02:00

102 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Der Bildbetrachter.
*
* Ohne dieses Skript ist ein vergrößerbares Bild schlicht ein Verweis auf die große Fassung: ein
* Klick öffnet sie, zurück führt die Zurück-Taste. Das ist die Grundlage, und sie funktioniert
* immer. Dieses Skript fängt den Klick ab und zeigt das Bild stattdessen über der Seite - mit
* Blättern, wenn es zu einer Galerie gehört.
*
* Benutzt wird <dialog>: der Browser bringt damit das Fangen des Fokus, das Schließen mit Escape
* und die Auszeichnung als Dialog schon mit. Eine nachgebaute Fassung aus <div> und Tastatur-
* abfragen wäre mehr Code und weniger zugänglich.
*/
(() => {
const zoomable = [...document.querySelectorAll('a[data-zoom]')];
if (0 === zoomable.length) {
return;
}
const dialog = document.createElement('dialog');
dialog.className = 'zoom-dialog';
dialog.innerHTML = `
<figure class="zoom-figure">
<img class="zoom-image" alt="">
<figcaption class="zoom-caption"></figcaption>
</figure>
<button class="zoom-close" type="button" aria-label="Schließen">×</button>
<button class="zoom-prev" type="button" aria-label="Vorheriges Bild">‹</button>
<button class="zoom-next" type="button" aria-label="Nächstes Bild">›</button>
<p class="zoom-counter" aria-live="polite"></p>
`;
document.body.append(dialog);
const bild = dialog.querySelector('.zoom-image');
const beschriftung = dialog.querySelector('.zoom-caption');
const zaehler = dialog.querySelector('.zoom-counter');
const zurueck = dialog.querySelector('.zoom-prev');
const vor = dialog.querySelector('.zoom-next');
/** Die Bilder, zwischen denen geblättert wird: die der Galerie, sonst nur dieses eine. */
const gruppeVon = (link) => {
const galerie = link.closest('[data-zoom-group]');
return galerie ? [...galerie.querySelectorAll('a[data-zoom]')] : [link];
};
let gruppe = [];
let stelle = 0;
const zeige = (index) => {
stelle = (index + gruppe.length) % gruppe.length;
const link = gruppe[stelle];
const inneres = link.querySelector('img');
bild.src = link.href;
bild.alt = inneres ? inneres.alt : '';
const text = link.dataset.caption || '';
beschriftung.textContent = text;
beschriftung.hidden = '' === text;
const mehrere = gruppe.length > 1;
zurueck.hidden = !mehrere;
vor.hidden = !mehrere;
zaehler.hidden = !mehrere;
zaehler.textContent = mehrere ? `${stelle + 1} von ${gruppe.length}` : '';
};
for (const link of zoomable) {
link.addEventListener('click', event => {
// Mit gedrückter Zusatztaste oder mittlerer Maustaste bleibt es ein normaler Verweis:
// wer ein Bild in einem neuen Reiter öffnen will, soll das können.
if (event.metaKey || event.ctrlKey || event.shiftKey || 1 === event.button) {
return;
}
event.preventDefault();
gruppe = gruppeVon(link);
zeige(gruppe.indexOf(link));
dialog.showModal();
});
}
zurueck.addEventListener('click', () => zeige(stelle - 1));
vor.addEventListener('click', () => zeige(stelle + 1));
dialog.querySelector('.zoom-close').addEventListener('click', () => dialog.close());
// Ein Klick neben das Bild schließt - erwartet, und der Dialog selbst ist die Fläche daneben.
dialog.addEventListener('click', event => {
if (event.target === dialog) {
dialog.close();
}
});
dialog.addEventListener('keydown', event => {
if (1 === gruppe.length) {
return;
}
if ('ArrowLeft' === event.key) {
event.preventDefault();
zeige(stelle - 1);
}
if ('ArrowRight' === event.key) {
event.preventDefault();
zeige(stelle + 1);
}
});
})();