Bri-Tunes/public/js/lightbox.js

65 lines
1.9 KiB
JavaScript

(function () {
'use strict';
// Build overlay DOM once, append to body.
const overlay = document.createElement('div');
overlay.id = 'lb-overlay';
overlay.setAttribute('aria-modal', 'true');
overlay.setAttribute('role', 'dialog');
overlay.innerHTML =
'<div class="lb-container">' +
'<button class="lb-close" aria-label="Close">\u00d7</button>' +
'<img class="lb-img" src="" alt="">' +
'</div>';
document.body.appendChild(overlay);
const container = overlay.querySelector('.lb-container');
const img = overlay.querySelector('.lb-img');
const closeBtn = overlay.querySelector('.lb-close');
let closing = false;
function open(src, alt) {
if (closing) return;
img.src = src;
img.alt = alt || '';
overlay.classList.remove('lb-closing');
overlay.classList.add('lb-open');
document.body.style.overflow = 'hidden';
}
function close() {
if (!overlay.classList.contains('lb-open') || closing) return;
closing = true;
overlay.classList.add('lb-closing');
// Wait for the shrink animation to finish before hiding.
overlay.addEventListener('animationend', function onEnd() {
overlay.removeEventListener('animationend', onEnd);
overlay.classList.remove('lb-open', 'lb-closing');
img.src = '';
document.body.style.overflow = '';
closing = false;
}, { once: true });
}
// Open on any [data-lightbox] image click.
document.addEventListener('click', (e) => {
const trigger = e.target.closest('[data-lightbox]');
if (trigger) {
e.preventDefault();
e.stopPropagation();
open(trigger.src || trigger.dataset.src, trigger.alt);
return;
}
// Close when clicking the backdrop (overlay itself, not the container).
if (e.target === overlay) close();
});
closeBtn.addEventListener('click', close);
// Keyboard: Escape closes.
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') close();
});
})();