Настройка галереи изображений товара (swiper/slider) 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка галереи изображений товара (swiper/slider) 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1181
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    813
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка галереи изображений товара (swiper/slider) 1С-Битрикс

Стандартный шаблон catalog.element в Битриксе рендерит дополнительные изображения товара (MORE_PHOTO) как набор тегов <img> без какой-либо галерейной логики. Магазин подключает Swiper, галерея работает на главной странице, но в карточке товара слайдер инициализируется до того, как компонент отдал HTML — и получает пустой контейнер. Это классическая проблема порядка выполнения скриптов в Битриксе.

Данные изображений в компоненте catalog.element

Компонент собирает все изображения товара в $arResult['MORE_PHOTO'] — массив путей к уже ресайзенным картинкам. Оригиналы хранятся в b_iblock_element.DETAIL_PICTURE и свойстве MORE_PHOTO (тип F, множественное). Для слайдера обычно нужны два размера: миниатюра для превью-полоски и полноразмерная для основного слайда.

В шаблоне template.php компонента:

<?php
$slides = [];
foreach ($arResult['PROPERTIES']['MORE_PHOTO']['FILE_VALUE'] as $fileArr) {
    $thumb = \CFile::ResizeImageGet($fileArr['ID'], ['width' => 80, 'height' => 80], BX_RESIZE_IMAGE_PROPORTIONAL);
    $full  = \CFile::ResizeImageGet($fileArr['ID'], ['width' => 800, 'height' => 800], BX_RESIZE_IMAGE_PROPORTIONAL);
    $slides[] = [
        'thumb' => $thumb['src'],
        'full'  => $full['src'],
        'alt'   => htmlspecialcharsEx($fileArr['DESCRIPTION'] ?: $arResult['NAME']),
    ];
}
?>

Разметка для Swiper

Swiper ожидает строгую структуру .swiper > .swiper-wrapper > .swiper-slide. Любое отклонение — и библиотека не найдёт слайды. Основной слайдер и слайдер миниатюр — два отдельных экземпляра Swiper, связанных через параметр thumbs.swiper:

<div class="swiper product-main-swiper" id="productMainSwiper">
    <div class="swiper-wrapper">
        <?php foreach ($slides as $slide): ?>
        <div class="swiper-slide">
            <img src="<?= $slide['full'] ?>" alt="<?= $slide['alt'] ?>" loading="lazy">
        </div>
        <?php endforeach; ?>
    </div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
</div>

<div class="swiper product-thumbs-swiper" id="productThumbsSwiper">
    <div class="swiper-wrapper">
        <?php foreach ($slides as $slide): ?>
        <div class="swiper-slide">
            <img src="<?= $slide['thumb'] ?>" alt="" loading="lazy">
        </div>
        <?php endforeach; ?>
    </div>
</div>

Инициализация и порядок скриптов

Ключевая проблема Битрикса: $APPLICATION->AddHeadScript() добавляет скрипты в <head>, а компонент рендерится позже в <body>. Swiper подключён в head, но new Swiper() вызывается в inline-скрипте шаблона — DOM ещё не готов.

Правильное решение — отложенная инициализация через DOMContentLoaded или через пролог/эпилог. В шаблоне компонента:

document.addEventListener('DOMContentLoaded', function () {
    const thumbsSwiper = new Swiper('#productThumbsSwiper', {
        slidesPerView: 4,
        spaceBetween: 8,
        watchSlidesProgress: true,
    });
    new Swiper('#productMainSwiper', {
        spaceBetween: 0,
        thumbs: { swiper: thumbsSwiper },
        keyboard: { enabled: true },
    });
});

Lazy loading и LCP

loading="lazy" на первом слайде убивает LCP — браузер откладывает загрузку главного изображения товара. Первый слайд должен грузиться без lazy:

foreach ($slides as $i => $slide):
    $loading = $i === 0 ? 'eager' : 'lazy';

Также стоит добавить fetchpriority="high" на первый слайд — это подсказка браузеру повысить приоритет запроса.

Смена изображений при выборе SKU

Когда пользователь выбирает торговое предложение, Битрикс через AJAX обновляет блок цены и наличия. Галерея при этом не меняется — она привязана к родительскому элементу. Чтобы синхронизировать: слушать событие onSaleComponentOfferSelect (стандартное событие Битрикса), получать offerId, запрашивать фото предложения через кастомный AJAX-экшн и пересоздавать слайдер с новыми данными через swiper.destroy() + реинициализацию.