← Все статьи

Туториалы

Зум изображения при наведении мыши — лайтбокс без библиотеки

Галереи, магазины, фотобанки — миниатюры повсюду. Чтобы увидеть изображение целиком, нужно кликнуть, подождать, вернуться назад. Это правило добавляет предпросмотр при наведении мыши: наводишь мышь на миниатюру, более крупная версия появляется рядом с курсором. Лёгкий лайтбокс без какой-либо библиотеки.

Правило

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 миниатюры и полного фото, найди разницу.

Ловушки

Смотри также

Установи JustZix — и смотри фото, не кликая по каждому.

Оцени эту статью

Оценок пока нет — оцени первым.

Попробуй сам

Установи JustZix и вставь любой сниппет из этой статьи. Две минуты от нуля до работающего правила на всех твоих устройствах.

Получить JustZix

Возможности · Как это работает · Примеры · Применение