lightbox.js
1 window.addEventListener("load", function () { 2 // Prepare modal 3 const modal = document.createElement('div'); 4 modal.id = 'zoom-modal'; 5 Object.assign(modal.style, { 6 display: 'none', 7 position: 'fixed', 8 inset: '0', 9 background: 'rgba(0,0,0,0.8)', 10 justifyContent: 'center', 11 alignItems: 'center', 12 zIndex: '9999', 13 cursor: 'zoom-out', 14 }); 15 modal.innerHTML = '<img src="" style="max-width:90vw; max-height:90vh;">'; 16 document.body.appendChild(modal); 17 18 const modalImg = modal.querySelector('img'); 19 const listenersMap = new WeakMap(); 20 21 const setupZoom = (img) => { 22 const isInLink = img.closest('a') !== null; 23 24 // Remove old click listener if present 25 if (listenersMap.has(img)) { 26 img.removeEventListener('click', listenersMap.get(img)); 27 listenersMap.delete(img); 28 } 29 30 // Set cursor & zoom only if image is large enough & not inside a link 31 if (!isInLink && img.naturalWidth > 128 && img.naturalHeight > 128) { 32 img.style.cursor = 'zoom-in'; 33 34 const clickHandler = () => { 35 modalImg.src = img.src; 36 modal.style.display = 'flex'; 37 }; 38 39 img.addEventListener('click', clickHandler); 40 listenersMap.set(img, clickHandler); 41 } else { 42 // Image too small or inside link: cursor to pointer (if link) or default 43 img.style.cursor = isInLink ? 'pointer' : 'default'; 44 } 45 }; 46 47 document.querySelectorAll('img').forEach(img => { 48 if (img.complete) { 49 setupZoom(img); 50 } else { 51 img.addEventListener('load', () => setupZoom(img)); 52 } 53 }); 54 55 modal.addEventListener('click', () => { 56 modal.style.display = 'none'; 57 modalImg.src = ''; 58 }); 59 60 window.addEventListener('keydown', (event) => { 61 if (event.key === 'Escape') { 62 modal.style.display = 'none'; 63 modalImg.src = ''; 64 } 65 }); 66 });