/ html / assets / js / lightbox.js
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  });