Как сделать смену картинки при наведении в каталоге товаров

    При разработке интернет-магазина часто возникает задача: при наведении курсора на товар в списке одно изображение заменяется другим. На мобильных устройствах аналогичный эффект достигается свайпом (смахиванием) или тапом. Готовые плагины для такой функциональности найти сложно, но реализовать её можно самостоятельно с помощью JavaScript и CSS. В этой статье разберём простой и рабочий способ без использования сторонних библиотек.

    Принцип работы механики

    На десктопе используется событие mouseenter для замены основного изображения на альтернативное (например, второй ракурс товара). При mouseleave картинка возвращается к исходной. На мобильных устройствах событие mouseenter не срабатывает, поэтому применяется событие touchstart или click, а также можно добавить поддержку свайпа через touchmove.

    Базовая HTML-структура

    Каждый товар в каталоге представляет собой контейнер с двумя изображениями: основное (видимое по умолчанию) и скрытое (альтернативное). Пример:

    <div class=\"product\">
      <img src=\"front.jpg\" class=\"main-img\" alt=\"Товар\">
      <img src=\"side.jpg\" class=\"alt-img\" style=\"display:none\" alt=\"Товар вид сбоку\">
    </div>

    JavaScript для десктопа и мобильных

    Создадим универсальный скрипт, который определяет тип устройства и применяет нужное событие. Для десктопа используем mouseenter/mouseleave, для мобильных - touchstart/touchend. Пример кода:

    document.querySelectorAll('.product').forEach(function(product) {
      var mainImg = product.querySelector('.main-img');
      var altImg = product.querySelector('.alt-img');
    
      function showAlt() {
        mainImg.style.display = 'none';
        altImg.style.display = 'block';
      }
    
      function showMain() {
        mainImg.style.display = 'block';
        altImg.style.display = 'none';
      }
    
      if (window.innerWidth > 768) {
        product.addEventListener('mouseenter', showAlt);
        product.addEventListener('mouseleave', showMain);
      } else {
        product.addEventListener('touchstart', function(e) {
          e.preventDefault();
          if (altImg.style.display === 'block') {
            showMain();
          } else {
            showAlt();
          }
        });
      }
    });

    Поддержка свайпа на мобильных

    Чтобы реализовать именно смахивание (свайп), можно отслеживать координаты касания. Если пользователь проводит пальцем влево или вправо - меняем картинку. Для этого добавляем обработчики touchstart и touchmove:

    var startX;
    product.addEventListener('touchstart', function(e) {
      startX = e.touches[0].clientX;
    });
    product.addEventListener('touchmove', function(e) {
      var diff = startX - e.touches[0].clientX;
      if (Math.abs(diff) > 50) {
        showAlt();
      }
    });
    product.addEventListener('touchend', function() {
      setTimeout(showMain, 2000);
    });

    Альтернатива с CSS-анимацией

    Иногда для смены изображения достаточно CSS-свойств. Например, можно использовать background-image и псевдокласс :hover:

    .product {
      background-image: url('front.jpg');
      transition: background-image 0.3s;
    }
    .product:hover {
      background-image: url('side.jpg');
    }

    Но такой способ не поддерживает свайп на мобильных и требует дополнительной обработки через JavaScript.

    Почему сложно найти готовые плагины

    Большинство плагинов для каталогов (например, для WooCommerce или OpenCart) встроенную смену изображений уже имеют, но их сложно адаптировать под нестандартные требования. Универсальные jQuery-плагины для этой задачи редки, так как логика сильно зависит от верстки конкретного магазина. Проще написать 10-15 строк кода, чем искать и настраивать стороннее решение.

    Советы по оптимизации

    • Сжимайте изображения: используйте WebP или AVIF для ускорения загрузки.
    • Lazy loading: загружайте альтернативные картинки только при наведении, чтобы не тормозить страницу.
    • Тестируйте на реальных устройствах: эмуляция в браузере не всегда корректно обрабатывает touch-события.

    Часто задаваемые вопросы