1/** 2 * image-lightbox.js 3 * ÐÑгкий lightbox без завиÑимоÑÑей Ð´Ð»Ñ Ð¸Ð·Ð¾Ð±Ñажений в richtext. 4 * Ðоведение: 5 * - клик по каÑÑинке в .fond-richtext оÑкÑÑÐ²Ð°ÐµÑ Ð¾Ð²ÐµÑлей 6 * - повÑоÑнÑй клик по каÑÑинке в овеÑлее пеÑеклÑÑÐ°ÐµÑ Ð·Ñм 7 * - ESC или клик по ÑÐ¾Ð½Ñ Ð·Ð°ÐºÑÑÐ²Ð°ÐµÑ 8 */ 9(function () { 10 'use strict'; 11 12 function ensureLightbox() { 13 var existing = document.getElementById('imageLightbox'); 14 if (existing) return existing; 15 16 var el = document.createElement('div'); 17 el.id = 'imageLightbox'; 18 el.className = 'image-lightbox'; 19 el.innerHTML = 20 '<div class="image-lightbox__backdrop" data-action="close"></div>' + 21 '<div class="image-lightbox__dialog" role="dialog" aria-modal="true">' + 22 ' <button class="image-lightbox__close" type="button" aria-label="ÐакÑÑÑÑ" data-action="close">Ã</button>' + 23 ' <div class="image-lightbox__figure">' + 24 ' <img class="image-lightbox__img" alt="" />' + 25 ' <div class="image-lightbox__caption" hidden></div>' + 26 ' </div>' + 27 '</div>'; 28 29 document.body.appendChild(el); 30 31 // ÐÑÑÑаиваем ÑÑили, ÑÑÐ¾Ð±Ñ Ð½Ðµ плодиÑÑ Ð¾ÑделÑнÑй CSS-Ñайл 32 var style = document.createElement('style'); 33 style.textContent = 34 '.image-lightbox{position:fixed;inset:0;z-index:30000;display:none}' + 35 '.image-lightbox.is-open{display:block}' + 36 '.image-lightbox__backdrop{position:absolute;inset:0;background:rgba(0,0,0,.72)}' + 37 '.image-lightbox__dialog{position:relative;max-width:min(1100px,calc(100% - 32px));max-height:calc(100% - 32px);margin:16px auto;display:flex;align-items:center;justify-content:center}' + 38 '.image-lightbox__figure{display:flex;flex-direction:column;align-items:center;gap:12px;max-width:100%;max-height:calc(100vh - 64px)}' + 39 '.image-lightbox__img{max-width:100%;max-height:calc(100vh - 64px);border-radius:12px;box-shadow:0 18px 60px rgba(0,0,0,.45);cursor:zoom-in;transform-origin:center;transition:transform .18s ease}' + 40 '.image-lightbox__img.is-zoomed{transform:scale(1.8);cursor:zoom-out}' + 41 '.image-lightbox__caption{max-width:min(840px,calc(100vw - 64px));padding:10px 14px;border-radius:14px;background:rgba(17,17,17,.42);color:rgba(255,255,255,.92);font-size:14px;line-height:1.5;text-align:center;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}' + 42 '.image-lightbox__close{position:absolute;top:10px;right:10px;width:40px;height:40px;border-radius:999px;border:1px solid rgba(255,255,255,.25);background:rgba(0,0,0,.35);color:#fff;font-size:22px;line-height:1;display:flex;align-items:center;justify-content:center}' + 43 '.image-lightbox__close:hover{background:rgba(0,0,0,.55)}'; 44 document.head.appendChild(style); 45 46 // ÐакÑÑÑие по ÐºÐ»Ð¸ÐºÑ 47 el.addEventListener('click', function (e) { 48 var t = e.target; 49 if (!t) return; 50 if (t.getAttribute && t.getAttribute('data-action') === 'close') { 51 close(el); 52 return; 53 } 54 55 // Ðлик по пÑÑÑÐ¾Ð¼Ñ Ð¼ÐµÑÑÑ Ð²Ð¾ÐºÑÑг изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ (внÑÑÑи диалога) Ñоже закÑÑваеÑ. 56 // ÐÑи ÑÑом клик по Ñамой каÑÑинке оÑÑавлÑем под зÑм. 57 if (t.classList && t.classList.contains('image-lightbox__img')) return; 58 if (t.closest && t.closest('.image-lightbox__dialog')) { 59 close(el); 60 } 61 }); 62 63 // ÐÑм по ÐºÐ»Ð¸ÐºÑ Ð½Ð° каÑÑинке 64 var img = el.querySelector('.image-lightbox__img'); 65 if (img) { 66 img.addEventListener('click', function (e) { 67 e.preventDefault(); 68 img.classList.toggle('is-zoomed'); 69 }); 70 } 71 72 // ESC 73 document.addEventListener('keydown', function (e) { 74 if (e.key === 'Escape' && el.classList.contains('is-open')) { 75 close(el); 76 } 77 }); 78 79 return el; 80 } 81 82 function open(src, alt) { 83 var lb = ensureLightbox(); 84 var img = lb.querySelector('.image-lightbox__img'); 85 var captionEl = lb.querySelector('.image-lightbox__caption'); 86 if (!img) return; 87 img.classList.remove('is-zoomed'); 88 img.src = src; 89 img.alt = alt || ''; 90 if (captionEl) { 91 var caption = arguments.length > 2 ? arguments[2] : ''; 92 captionEl.textContent = caption || ''; 93 captionEl.hidden = !caption; 94 } 95 lb.classList.add('is-open'); 96 document.body.style.overflow = 'hidden'; 97 } 98 99 function close(lb) { 100 var img = lb.querySelector('.image-lightbox__img'); 101 var captionEl = lb.querySelector('.image-lightbox__caption'); 102 if (img) { 103 img.classList.remove('is-zoomed'); 104 img.src = ''; 105 } 106 if (captionEl) { 107 captionEl.textContent = ''; 108 captionEl.hidden = true; 109 } 110 lb.classList.remove('is-open'); 111 document.body.style.overflow = ''; 112 } 113 114 function getCaption(img) { 115 if (!img) return ''; 116 var explicitCaption = img.getAttribute('data-lightbox-caption'); 117 if (explicitCaption) return explicitCaption.trim(); 118 119 var figure = img.closest ? img.closest('figure') : null; 120 if (figure) { 121 var figcaption = figure.querySelector('figcaption');
122 if (figcaption && figcaption.textContent) { 123 return figcaption.textContent.trim(); 124 } 125 } 126 127 var title = img.getAttribute('title'); 128 if (title) return title.trim(); 129 130 var alt = img.getAttribute('alt'); 131 return alt ? alt.trim() : ''; 132 } 133 134 function shouldHandle(img) { 135 if (!img) return false; 136 if (!img.src) return false; 137 // еÑли ÑÑо Ñже каÑÑинка внÑÑÑи lightbox 138 if (img.closest && img.closest('#imageLightbox')) return false; 139 // либо изобÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð² richtext, либо ÑÐ²Ð½Ð°Ñ Ð¿Ð¾Ð¼ÐµÑка 140 if (img.classList && img.classList.contains('js-lightbox-img')) return true; 141 if (!(img.closest && (img.closest('.fond-richtext') || img.closest('.reading-prose')))) return false; 142 return true; 143 } 144 145 function init() { 146 document.addEventListener('click', function (e) { 147 var target = e.target; 148 if (!(target && target.tagName === 'IMG')) return; 149 if (!shouldHandle(target)) return; 150 e.preventDefault(); 151 open(target.src, target.alt, getCaption(target)); 152 }); 153 } 154 155 if (document.readyState === 'loading') { 156 document.addEventListener('DOMContentLoaded', init); 157 } else { 158 init(); 159 } 160})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.