Зум изображения при наведении мыши — лайтбокс без библиотеки
Галереи, магазины, фотобанки — миниатюры повсюду. Чтобы увидеть изображение целиком, нужно кликнуть, подождать, вернуться назад. Это правило добавляет предпросмотр при наведении мыши: наводишь мышь на миниатюру, более крупная версия появляется рядом с курсором. Лёгкий лайтбокс без какой-либо библиотеки.
Правило
JavaScript правила — URL-паттерн для галереи, которую ты используешь, или * глобально:
const box = document.createElement('img');
box.style.cssText =
'position:fixed;pointer-events:none;z-index:99999;max-width:40vw;' +
'max-height:80vh;box-shadow:0 8px 32px rgba(0,0,0,.4);' +
'border-radius:8px;display:none';
document.body.appendChild(box);
addEventListener('mouseover', (e) => {
const img = e.target.closest('img');
if (!img) return;
box.src = img.currentSrc || img.src;
box.style.display = 'block';
});
addEventListener('mousemove', (e) => {
box.style.left = (e.clientX + 24) + 'px';
box.style.top = (e.clientY + 24) + 'px';
});
addEventListener('mouseout', () => { box.style.display = 'none'; });
Как это работает
Один элемент предпросмотра
Мы создаём ровно один <img> и переиспользуем его, меняя только его src. Никакой очистки DOM, никаких утечек.
pointer-events: none
Предпросмотр находится поверх страницы. Без pointer-events: none он сам ловил бы события мыши — курсор «входил» бы в предпросмотр, mouseout срабатывал бы ошибочно, и предпросмотр мерцал бы. С этим правилом предпросмотр прозрачен для мыши.
currentSrc против src
img.currentSrc — это версия, которую браузер реально выбрал из srcset — обычно чётче, чем src. Мы используем её первой, с src как резервом.
position: fixed плюс client-координаты
position: fixed позиционирует предпросмотр относительно окна, а e.clientX/clientY — позиция курсора относительно окна — они совпадают, поэтому предпросмотр следует за курсором независимо от прокрутки.
Вариант — полный размер вместо миниатюры
Во многих галереях у миниатюры URL вроде .../thumb/foto.jpg, тогда как полный размер — .../large/foto.jpg. Замени box.src на переписанный адрес:
box.src = (img.currentSrc || img.src).replace('/thumb/', '/large/');
Паттерн варьируется от сайта к сайту — посмотри на src миниатюры и полного фото, найди разницу.
Ловушки
- CSS-фоны — не изображения. Фото, вставленные как
background-image, не являются элементами<img>— это правило их не поймает. - Ленивая загрузка. У миниатюры с
loading="lazy", к которой ты ещё не прокрутил, может не бытьsrc. Как только она видима, работает нормально. - Крошечные иконки. Правило ловит каждый
<img>, включая иконки UI. Чтобы целиться только в галерею, сузь селектор, напримерe.target.closest('.gallery img').
Смотри также
- Примеры — сниппет зума и другой готовый код
- Auto-pager — ещё одно правило «добавь недостающую функцию»
- Мини-IDE во вкладке — где тестировать правила вроде этого
Установи JustZix — и смотри фото, не кликая по каждому.
Оцени эту статью
Оценок пока нет — оцени первым.