Фотогалерея товаров для интернет-магазина.

Вступление.

В различных интернет-магазинах, в карточке товара, очень часто используется фотогалерея, с помощью которой этот товар можно рассмотреть подробнее, в разных проекциях. В этой статье мы подробно рассмотрим создание такой галереи для интернет-магазина. Так же мы создадим удобную, универсальную систему управления этой галереей.

Для начала, давайте определимся со структурой фотогалереи и способами управления ею.

Итак, структура галереи для интернет-магазина будет состоять из трёх основных блоков:
1. блок с тумбами картинок;
2. блок, куда будет выводится полноразмерная картинка;
3. блок с кнопками навигации по галереи.

Для управления сменой картинок, давайте используем максимально возможные варианты:
— кнопками навигации «предыдущая», «следующая», «первая», «последняя»;
— кликом по тумбе картинки;
— кликом по большой картинке, при этом будет выводится следующая картинка;
— клавишами со стрелочками «влево» и «вправо»;
— колёсиком мышки.

Вроде со всем определились, ничего не упустили. Давайте приступим непосредственно к созданию фотогалереи.

HTML-вёрстка галереи для интернет-магазина.

HTML-вёрстка галереи очень простая и, как писалось ранее, состоит всего из трёх блоков:

В данном варианте, блок с тумбами фотографий расположен слева от основного фото. Вы его можете расположить и справа, и вверху, и под основной фотографией — это ни как не повлияет на функционирование галереи.

Тумбы и большие фото разнесены по разным папкам — thumbnail и photos соответственно. Их можно было бы положить и в одну папку, добавив именам картинок префиксы, чтобы различать, где тумба, а где полноразмерное фото. При этом сам js-скрипт не изменится.
Как видите из вёрстки, я не стал оборачивать ни тумбы, ни кнопки навигации в дополнительные <div> или <li> — в этом нет совершенно никакой необходимости и незачем усложнять вёрстку и замусоривать её лишними элементами.

Ещё один немаловажный момент. В блоке <div class="photo-box"></div> по умолчанию находится фотография. Это необходимо для того, чтобы пока не загрузился скрипт, в галерее не было пустого места.

Запомните, это очень важно.
Не нужно оборачивать тумбу ссылкой, используя её href, как указатель на полноразмерную фотографию. Как с точки зрения семантики, так и с точки зрения СЕО — тэг <a> должен использоваться только для формирования ссылок, ведущих на другие страницы сайта или другой интернет-ресурс.
JS-скрипту, для вывода полноразмерного фото, достаточно src тумбы.

Таблица стилей галереи для интернет-магазина.

Представлены только стили, относящиеся непосредственно к самой галерее.

Очень важно.
Для уменьшения размера таблицы стилей, я не буду приводить свойства с вендорными префиксами, обеспечивающими кроссбраузерность. Не забывайте прописывать их при реализации своих проектов.

Пишем JS-скрипт фотогалереи для интернет-магазина.

И вот мы подошли к написанию JS-скрипта вывода и управления галереей интернет-магазина. Первое, с чего мы начнём, это создадим анонимную самозапускающуюся функцию, внутри которой и будет расположен наш код. Вообще, надо взять за правило ограничивать область видимости скрипта, чтобы не было конфликтов с другими JS-скриптами подключенными к странице. Мало ли, совпадут названия переменных или функций…

При написании JS-скрипта мы будем использовать конструкцию Class. Это позволит создать несколько экземпляров галереи товаров для интернет-магазина на одной странице.

Создание экземпляров фотогалерей товаров для интернет-магазина.

В-первую очередь, создадим коллекцию фотогалерей, которые расположены на странице. Далее, с помощью метода for...of переберём полученную коллекцию, при этом мы выполним следующие действия:
— создадим экземпляр текущей галереи, используя конструктор класса Gallery;
— зарегистрируем обработчики событий.

Весь дальнейший JS-код мы будем писать внутри конструкции class Gallery { ... }.

Прежде всего рассмотрим конструктор класса Gallery. Конструктор инициализирует ряд объектов и переменных, содержащих информацию об экземпляре галереи. В качестве аргумента конструктор принимает объект галереи товара, экземпляр которого создаётся в данный момент.

Конструктор, кроме инициализации объектов и переменных, вызывает функцию registerEventsHandler(), которая регистрирует обработчики событий на странице:

Вывод полноразмерной фотографии в галерее для интернет-магазина.

Теперь рассмотрим функцию вывода полноразмерной фотографии — showPhoto(). Аргументом этой функции является индекс или текущей тумбы, или рассчитанный функциями управления выводом полноразмерного фото.
Итак, на вход функции showPhoto поступил индекс. Считываем у тумбы с таким индексом значение атрибута src и заменяем в нём название папки, в которой хранятся фотографии с thumbnails на photos. В результате такой нехитрой операции получаем путь (src) к большой фотографии. Полученное значение присваиваем атрибуту src объекта image, в результате чего, на экран выводится фото в полный размер.

Код функции showPhoto() и комментарии к нему:

Ранее говорилось, что можно и тумбы, и полноразмерные фото можно положить в одну папку, присвоив им разные префиксы. Давайте посмотрим, что нужно изменить в функции showPhoto для этого. Обратите ещё раз внимание на строку:

Замените в ней thumbnails и photos на префикс_тумбы и префикс_фото соответственно. Больше ничего исправлять не нужно.

На данном этапе у нас уже есть вполне работоспособная фотогалерея товаров для интернет-магазина. Полноразмерные фото переключаются при клике по тумбе, но мы хотели сделать расширенное управление галереей. Давайте расширим функционал нашего js-скрипта.

Расширенное управление фотогалереей для интернет-магазина.

Прежде чем начинать разбираться с функциями управления галереей, нужно вспомнить основы JavaScript, а именно, взятие остатка %. Результат a % b – это остаток от деления a на b. На этом основано получение индекса очередной фотографии, который является аргументом функции showPhoto.

Листаем галерею с помощью кнопок навигации.

Для управления фотогалереей кнопками навигации будем использовать делегирование события. Обработчик события будем вешать не на каждую кнопку навигации, а на их родительский элемент control, сократив таким образом, значительное количество JS-кода. При срабатывании обработчика вызывается функция buttonControl(), в которой реализован весь алгоритм управления.

Код функции buttonControl() и комментарии к нему:

Листание галереи кликом по полноразмерной фотографии.

Вешаем на объект image обработчик события. Передаём функции showPhoto индекс очередного фото, равный остатку от деления увеличенного на единицу текущего индекса на количество фотографий в галерее.

При срабатывании обработчика события вызывается функция imageControl().

Теперь можно кликать по полноразмерному фото, листая галерею по кругу.

Листаем галерею стрелками «влево» и «вправо» на клавиатуре.

С помощью функции addEventListener вешаем на страницу с фотогалереей обработчик события keydown — нажатие на любую клавишу клавиатуры. При срабатывании обработчика события keydown, вызывается функция keyControl().
Поучаем код нажатой клавиши. Если этот код равен 37 (влево) или 39 (вправо), вызываем функцию showPhoto с соответствующим аргументом. В противном случае, прекращаем работу функции.

Код функции keyControl() и комментарии к нему:

Листаем галерею вращая колёсико мышки.

Управление выводом фото колёсиком мышки будет срабатывать только в том случае, если было наведение курсора на полноразмерную фотографию. Для этого обработчик события повесим на объект image.

Если наступило событие wheel — прокручивание колёсика мышки, вызывается функция wheelControl().
По значению свойства deltaY события wheel определяем направление вращения колёсика. Далее, вызываем функцию showPhoto с аргументом, зависящим от направления вращения.

Код функции wheelControl() и комментарии к нему:

Листаем галерею кликом по «тумбе» — маленькой фотографии.

Учитывая, что малоразмерных фотографий может быть очень много, снова используем делегирование событий. Повесим обработчик события на родительский элемент — объект thumbsBox и при срабатывании обработчика вызовем функцию thumbControl().

В функции thumbControl(), в-первую очередь, определяем картинку, по которой был сделан клик. Далее, нам необходимо определить индекс картинки в коллекции thumbs, чтобы передать этот индекс в функцию showPhoto() для вывода полноразмерного фото. И вот здесь у нас возникает проблема.
Индекс можно определить с помощью встроенного метода indexOf, но этот метод есть только у массива, у коллекции он отсутствует. Есть два варианта решения этой проблемы:
1. Преобразовать коллекцию thumbs в массив и далее спокойно использовать метод indexOf.
2. Заимствование (одалживание) метода. Мы берём (заимствуем) метод indexOf из обычного массива [].indexOf. И используем [].indexOf.call, чтобы выполнить его в контексте thumbs.

Посмотрим JS-код первого и второго вариантов:

Я не могу сказать, какой вариант более предпочтительный. Хотя мне кажется, что преобразование коллекции в массив при каждом клике по тумбе, более затратный по сравнению с одалживанием метода. Поэтому я выбрал вариант 2.
Хотелось бы в комментариях к статье прочитать ваше мнение. Возможно я ошибаюсь, а возможно, при таком количестве фото, без разницы, какой вариант использовать.

Полный код функции thumbControl() и комментарии к нему:

Заключение.

Итак, мы создали фотогалерею с универсальным управлением, которую можно использовать в интернет-магазине для вывода фотографий товаров. Конечно, это упрощённый по функционалу вариант, для того, чтобы вам было легче разобраться с работой галереи. Её функционал можно расширить, например, выделить тумбу текущей (просматриваемой) фотографии или заставить прокручиваться тумбы, при смене полноразмерного фото, можно использовать различную анимацию при появлении новой фотографии и т д. Возможно, в одной из следующих статей мы это всё и рассмотрим.

Комментарии

Всего: 10 комментариев
Требования при посте комментариев:
  1. Комментарии должны содержать вопросы и дополнения по статье, ответы на вопросы других пользователей.
    Комментарии содержащие обсуждение политики, будут безжалостно удаляться.
  2. Для удобства чтения Вашего кода, не забываейте его форматировать. Вы его можете подсветить код с помощью тега <pre>:
    <pre class="lang:xhtml"> - HTML;
    <pre class="lang:css"> - CSS;
    <pre class="lang:javascript"> - JavaScript.
  3. Если что-то не понятно в статье, постарайтесь указать более конкретно, что именно не понятно.
  • Если установить 2 такие галереи на одну страницу то работает только первая, как это исправить. Чтобы работали все. На второй галереи фото не переключаются.

    • Вальдемар Рома Ответить 5 июля 2018 в 23:04

      Данный скрипт и не предусматривает это, т. к. написан в функциональном стиле. Чтобы на одной странице работало несколько галерей, скрипт необходимо переписать в прототипном стиле: создать конструктор, который будет создавать экземпляры галерей, от которых будут наследоваться методы, отвечающие за работу галереи.
      При таком подходе, количество галерей ограничено только пределами разумного.

  • Можете мне тоже помочь? не работает с двумя галереями..

    • Вальдемар Яромир Ответить 5 января 2020 в 19:38

      Проверьте уникальность id у каждой галереи и их соответствие при вызове конструктора.

  • Не как не получается сделать две разные галереи на одной странице.

    • Вальдемар Роман Ответить 19 марта 2020 в 15:38

      Обновил архив. Оказывается в нём не доставало файлов. Смотрите HTML и JS с расширением prototype.
      Приношу извинения, за неполный архив.

  • загружаю страницу с компа, ни работает увеличение превью фото при клике на них, в чём может быть дело, все пути прописал верно, все фото отображаются.

    • Вальдемар Андрей Ответить 8 мая 2020 в 17:18

      Так трудно, что-либо посоветовать не видя вашей сборки. Посмотрите в консоли, есть ли какие-то ошибки скрипта js.

Добавить комментарий для Яромир

Ваш адрес email не будет опубликован. Обязательные поля помечены *