75 lines
2.4 KiB
JavaScript
75 lines
2.4 KiB
JavaScript
(() => {
|
||
const SELECTOR = 'a.map-image-link, img.map-image';
|
||
let lightbox = null;
|
||
let lightboxImg = null;
|
||
|
||
function ensureLightbox() {
|
||
if (lightbox) return lightbox;
|
||
|
||
lightbox = document.createElement('div');
|
||
lightbox.className = 'map-lightbox';
|
||
lightbox.setAttribute('aria-hidden', 'true');
|
||
|
||
const closeBtn = document.createElement('button');
|
||
closeBtn.type = 'button';
|
||
closeBtn.className = 'map-lightbox__close';
|
||
closeBtn.setAttribute('aria-label', 'Close map preview');
|
||
closeBtn.textContent = '×';
|
||
|
||
lightboxImg = document.createElement('img');
|
||
lightboxImg.className = 'map-lightbox__img';
|
||
lightboxImg.alt = 'Map preview';
|
||
|
||
const hint = document.createElement('div');
|
||
hint.className = 'map-lightbox__hint';
|
||
hint.textContent = 'Esc or click/tap outside to close';
|
||
|
||
lightbox.appendChild(closeBtn);
|
||
lightbox.appendChild(lightboxImg);
|
||
lightbox.appendChild(hint);
|
||
document.body.appendChild(lightbox);
|
||
|
||
closeBtn.addEventListener('click', closeLightbox);
|
||
lightbox.addEventListener('click', (ev) => {
|
||
if (ev.target === lightbox) closeLightbox();
|
||
});
|
||
document.addEventListener('keydown', (ev) => {
|
||
if (ev.key === 'Escape' && lightbox.classList.contains('is-open')) closeLightbox();
|
||
});
|
||
|
||
return lightbox;
|
||
}
|
||
|
||
function openLightbox(src, alt) {
|
||
if (!src) return;
|
||
ensureLightbox();
|
||
lightboxImg.src = src;
|
||
lightboxImg.alt = alt || 'Map preview';
|
||
lightbox.classList.add('is-open');
|
||
lightbox.setAttribute('aria-hidden', 'false');
|
||
document.body.classList.add('map-lightbox-open');
|
||
}
|
||
|
||
function closeLightbox() {
|
||
if (!lightbox) return;
|
||
lightbox.classList.remove('is-open');
|
||
lightbox.setAttribute('aria-hidden', 'true');
|
||
document.body.classList.remove('map-lightbox-open');
|
||
setTimeout(() => {
|
||
if (!lightbox.classList.contains('is-open')) lightboxImg.removeAttribute('src');
|
||
}, 260);
|
||
}
|
||
|
||
document.addEventListener('click', (ev) => {
|
||
const target = ev.target instanceof Element ? ev.target.closest(SELECTOR) : null;
|
||
if (!target) return;
|
||
|
||
const img = target.matches('img.map-image') ? target : target.querySelector('img.map-image');
|
||
const src = img ? (img.currentSrc || img.src) : target.getAttribute('href');
|
||
if (!src) return;
|
||
|
||
ev.preventDefault();
|
||
ev.stopPropagation();
|
||
openLightbox(src, img ? img.alt : 'Map preview');
|
||
});
|
||
})();
|