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

Вступление.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Теперь объявим ряд переменных и присвоим им значения:

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

У вас может возникнуть вопрос: а зачем было создавать коллекцию элементов img, когда можно повесить обработчик события только на их родительский элемент <div class="thumbs"> и, далее, с помощью делегирования события определять, по какой тумбе был сделан клик? Конечно, можно было бы воспользоваться делегированием, но нам для навигации по галерее нужны индексы тумб. Так что нам всё-равно бы пришлось делать их обход, присваивая индексы. А в предложенном мною варианте, мы одновременно и присваиваем индексы, и вешаем обработчик события на каждую тумбу.

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

Теперь настало время привести полный код данной функции:

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

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

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

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

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

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

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

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

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

Здесь мы применим делегирование событий, которое упоминали ранее. Давайте по шагам рассмотрим, как происходит управление фотогалереей интернет-магазина навигационными кнопками:

  • 1

    С помощью функции addEventListener вешаем обработчик события на объект control.

  • 2

    Используя делегирования события, определяем, по какому дочернему элементу (button) объекта control был сделан клик.

  • 3

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

  • 4

    Вызываем функцию showPhoto, аргумент которой зависит от функционала нажатой кнопки.

Остановимся подробнее на шагах 3 и 4. В шаге 3 мы получили функционал кнопки. Теперь нужно решить, каким способом мы сопоставим этому функционалу соответствующий ему аргумент функции showPhoto, который является индексом тумбы полноразмерной фотографии. Обычно это делается с помощью конструкций if else или switch.
Но есть ещё один способ, который заменяет эти конструкции — использование объектного литерала. Мы сэкономим несколько строчек кода, при сохранении функциональности. Давайте и остановимся на этом способе.

Полный код функции управления галереей с помощью клавиш навигации:

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

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

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

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

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

JavaScript, который мы написали для фотогалереи, сделан в функциональном стиле. Скрипт достаточно простой и легко читается, его не сложно доработать, добавив нового функционала, но он обладает существенным недостатком — на одной странице мы можем разместить только одну такую галерею. В комментариях к статье отметили данный недостаток.
Давайте рассмотрим, какие изменения необходимо внести в JS-скрипт и HTML-вёрстку, чтобы на странице сайта можно было разместить несколько таких фотогалерей.

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

Продублируем HTML-вёрстку галереи и обернём каждую галерею контейнером <div> и присвоим им уникальные id, например, gallery_1 и gallery_2 соответственно.

Таблица стилей останется без изменений, поэтому приводить её здесь не имеет смысла.

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

Создадим конструктор Gallery, представляющий из себя функциональное выражение (Function Expression). С его помощью будут создаваться объекты экземпляров фотогалерей, размещённых на странице интернет-магазина. Свойствами конструктора будут DOM-элементы фотогалереи. Кроме этого, из конструктора вызовем функцию registerEvents, устанавливающую обработчики событий на странице с фотогалерей.

Как я писал в начале статьи, весь JS-код скрипта фотогалереи обёрнут анонимной самозапускающейся функцией. Для того, чтобы была возможность обратиться к конструктору из вне анонимной функции, запишем функцию-конструктор, как свойство объекта Window.

В конце HTML-вёрстки, перед закрывающим тегом </body>, запишем следующий код, который вызывая функцию-конструктор Gallery, создаёт экземпляры галерей. В качестве аргумента передаётся id галереи, экземпляр которой создаётся в данный момент:

Итак, после создания экземпляра объекта фотогалереи изображений со свойствами, значения которых соответствуют именно той галерее, id которой было передано, вызывается функция, регистрирующая обработчики событий, относящиеся именно к этой же галерее.
Обработчик назначается вызовом метода addEventListener, который привязывается к элементу, на котором событие регистрируется.

Запомните, это очень важно.
При использовании метода addEventListener теряется контекст вызова — this, который ссылается на текущий объект. Используя встроенный в JavaScript метод bind, можно напрямую передать контекст вызова в функцию обработчика события.

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

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

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

Комментарии

Всего: 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 не будет опубликован. Обязательные поля помечены *