Продвинутые функции

Offcanvas -- выезжающие панели

Централизованный API для работы с offcanvas-элементами (выезжающими панелями). Обеспечивает показ и скрытие панелей, swipe-функциональность и управление cookie. Панели построены на компоненте HSOverlay из Preline UI.

Доступ к API

API входит в собранный JS-бандл темы и доступен глобально после загрузки страницы:

window.waTheme.offcanvasAPI

Тема сама вызывает инициализацию при загрузке; вручную методы initOffcanvasElements() и initSwipeElements() нужно вызывать только после динамического добавления разметки.

Публичные методы

show(options)

Показывает offcanvas-панель. Может открыть существующую панель или создать новую динамически. Панель, созданная динамически, выезжает снизу (нижний лист).

Параметры (объект options):

ПараметрТипОписание
idstringID элемента offcanvas (обязательно)
htmlstringHTML-содержимое (если элемент нужно создать)
classNamestringДополнительные CSS-классы
autoOpenbooleanАвтоматически открыть (по умолчанию true)
cookieObjectНастройки cookie (см. ниже)
onClosefunctionCallback при закрытии

Настройки cookie:

ПараметрТипОписание
namestringИмя cookie
valuestringЗначение cookie
lifetimenumberВремя жизни в часах (по умолчанию 24)
triggerstringКогда устанавливать: 'open' или 'close'

Возвращает: объект вида { element }, где element — экземпляр HSOverlay (методы вызываются как result.element.open()), либо undefined, если панель не найдена и не передан html.

Примеры:

Открыть существующую панель:

window.waTheme.offcanvasAPI.show({
    id: 'my-offcanvas'
});

Создать и показать панель с HTML-содержимым:

window.waTheme.offcanvasAPI.show({
    id: 'dynamic-offcanvas',
    html: '<div class="p-4"><h3>Заголовок</h3><p>Содержимое панели</p></div>',
    className: 'custom-class'
});

С настройкой cookie и callback при закрытии:

window.waTheme.offcanvasAPI.show({
    id: 'promo-offcanvas',
    html: '<div class="text-center p-6"><h2>Скидка 20%!</h2><p>Только сегодня</p></div>',
    cookie: {
        name: 'promo_shown',
        value: '1',
        lifetime: 48,
        trigger: 'close'
    },
    onClose: (instance) => {
        console.log('Offcanvas закрыт');
    }
});

close(id)

Закрывает offcanvas-панель по ID.

window.waTheme.offcanvasAPI.close('my-offcanvas');

addSwipeToClose(target, options)

Добавляет swipe-to-close к любому offcanvas-элементу программно. target — селектор или DOM-элемент.

window.waTheme.offcanvasAPI.addSwipeToClose('#my-offcanvas', {
    swipeFullElement: true,
    ignoreInteractiveElements: false,
    minSwipeVelocity: 1.2
});

initOffcanvasElements()

Инициализирует все offcanvas-элементы на странице, найденные по селектору [data-offcanvas].

window.waTheme.offcanvasAPI.initOffcanvasElements();

initSwipeElements()

Инициализирует swipe-функциональность для элементов с классом .hs-offcanvas-swiper.

window.waTheme.offcanvasAPI.initSwipeElements();

disconnectObserver()

Отключает MutationObserver для экономии ресурсов.

window.waTheme.offcanvasAPI.disconnectObserver();

Открытие через data-атрибут

Offcanvas-панель можно открыть через атрибут data-hs-overlay на любом кликабельном элементе:

<button type="button" data-hs-overlay="#myOffcanvas">
    Открыть панель
</button>

<a href="javascript:;" data-hs-overlay="#myOffcanvas">
    Открыть панель
</a>

HTML-разметка offcanvas

Для размещения панели на сайте создайте блок в приложении Сайт — Блоки site.seller2_body_html и разместите там код. Пример панели, выезжающей снизу (такую разметку используют мобильные панели темы):

<!-- Кнопка-триггер -->
<button type="button"
        class="btn btn-theme btn-base"
        data-hs-overlay="#myCustomOffcanvas">
    Открыть панель
</button>

<!-- Offcanvas панель (выезжает снизу) -->
<div id="myCustomOffcanvas"
     class="hs-overlay hs-overlay-open:translate-y-0 translate-y-full flex flex-col fixed bottom-0 inset-x-0 transition-all duration-300 transform w-full max-h-screen z-overlay-offcanvas bg-white rounded-t-2xl dark:bg-neutral-800 hs-overlay-backdrop-open:bg-neutral-900/80 hidden"
     role="dialog"
     tabindex="-1"
     aria-labelledby="myCustomOffcanvasLabel">

    <!-- Заголовок -->
    <div class="flex justify-between items-center py-3 px-4 border-b dark:border-neutral-700">
        <h3 id="myCustomOffcanvasLabel" class="font-bold text-gray-800 dark:text-white">
            Заголовок панели
        </h3>
        <button type="button"
                class="size-8 inline-flex justify-center items-center rounded-full bg-gray-100 text-gray-800 hover:bg-gray-200 dark:bg-neutral-700 dark:text-neutral-400 dark:hover:bg-neutral-600"
                data-hs-overlay="#myCustomOffcanvas">
            <span class="sr-only">Закрыть</span>
            <svg class="size-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <path d="M18 6 6 18"></path>
                <path d="m6 6 12 12"></path>
            </svg>
        </button>
    </div>

    <!-- Содержимое -->
    <div class="p-4 overflow-y-auto">
        <p class="text-gray-800 dark:text-neutral-400">
            Содержимое offcanvas-панели.
        </p>
    </div>
</div>

Панель, выезжающая слева:

<div id="myLeftOffcanvas"
     class="hs-overlay hs-overlay-open:translate-x-0 -translate-x-full flex flex-col fixed top-0 start-0 transition-all duration-300 transform h-full w-full max-w-80 z-overlay-offcanvas bg-white border-e dark:bg-neutral-800 dark:border-neutral-700 hidden"
     role="dialog"
     tabindex="-1">
    <div class="p-4 overflow-y-auto">
        Содержимое панели
    </div>
</div>

Направления выезда

НаправлениеКлассы
Слеваhs-overlay-open:translate-x-0 -translate-x-full fixed top-0 start-0
Сверхуhs-overlay-open:translate-y-0 -translate-y-full fixed top-0 inset-x-0
Снизуhs-overlay-open:translate-y-0 translate-y-full fixed bottom-0 inset-x-0

В собранный CSS темы входят только перечисленные классы сдвига (-translate-x-full, -translate-y-full, translate-y-full); класса translate-x-full для выезда справа в сборке нет — при необходимости добавьте его собственным CSS.

Автоматическая инициализация через data-offcanvas

Добавьте атрибут data-offcanvas к элементу с JSON-конфигурацией для автоматической инициализации:

<div data-offcanvas='{"id": "example-offcanvas", "delay": 3}'>
    <div class="p-4">
        <h3>Заголовок</h3>
        <p>Содержимое offcanvas</p>
    </div>
</div>

Параметры data-offcanvas:

ПараметрТипОписание
idstringID создаваемого offcanvas-элемента
delaynumberЗадержка показа в секундах (0 = сразу, -1 = создать, но не открывать автоматически)
removebooleanУдалить исходный элемент после обработки
classNamestringДополнительные CSS-классы
cookieObjectНастройки cookie; если cookie уже установлена в заданное значение, панель не создаётся
<div data-offcanvas='{
    "id": "promo",
    "delay": 5,
    "remove": true,
    "cookie": {
        "name": "promo_seen",
        "value": "1",
        "trigger": "close"
    }
}'>
    <div class="text-center p-6">
        <h2>Скидка 20%!</h2>
        <p>Только сегодня</p>
    </div>
</div>

Swipe-функциональность

Для включения закрытия свайпом добавьте класс .hs-offcanvas-swiper к элементу внутри offcanvas:

<div id="my-offcanvas" class="hs-overlay ...">
    <div class="hs-offcanvas-swiper" data-params='{"threshold": 100}'>
        <!-- Содержимое -->
    </div>
</div>

Параметры data-params

Базовые параметры:

ПараметрТипПо умолчаниюОписание
thresholdnumber50Минимальное расстояние в px для закрытия
swipeFullElementbooleanfalseСвайп по всему offcanvas, а не только по handle
ignoreInteractiveElementsbooleantrueИгнорировать касания интерактивных элементов

Scroll-aware параметры:

ПараметрТипПо умолчаниюОписание
scrollAwarebooleantrueУмная детекция скролла vs свайпа
minSwipeDistancenumber30Минимальное расстояние свайпа в px
maxScrollOffsetnumber10Макс. отступ от верха для работы свайпа в px
minSwipeVelocitynumber1.0Минимальная скорость свайпа в px/ms
maxSwipeTimenumber200Макс. время для быстрого жеста в мс
minDistanceForVelocityChecknumber20Мин. расстояние перед анализом скорости в px

Режимы работы свайпа

Обычный режим (scrollAware: false) — простая логика: свайп вниз больше threshold = закрытие.

<div class="hs-offcanvas-swiper" data-params='{"threshold": 50, "scrollAware": false}'>
    <!-- Простой контент -->
</div>

Scroll-aware режим (scrollAware: true, по умолчанию) — умная детекция намерений пользователя:

  1. Первые 20px движения — offcanvas не двигается, работает только скролл
  2. После 20px — анализ скорости и времени жеста
  3. Быстрый жест (< 200ms, > 1.0 px/ms) — offcanvas начинает двигаться
  4. Медленное движение — продолжается обычный скролл
  5. При завершении — закрытие только для быстрых жестов
<div class="hs-offcanvas-swiper" data-params='{
    "threshold": 50,
    "swipeFullElement": true,
    "minSwipeVelocity": 1.2,
    "maxSwipeTime": 150
}'>
    <!-- Контент с возможностью скролла -->
</div>

Программное создание offcanvas

Полный пример создания offcanvas-панели через JavaScript:

// Создать и показать offcanvas с содержимым
window.waTheme.offcanvasAPI.show({
    id: 'cart-summary',
    html: `
        <div class="p-4">
            <h3 class="font-bold text-lg mb-4">Корзина</h3>
            <div class="hs-offcanvas-swiper">
                <p>Содержимое корзины</p>
            </div>
        </div>
    `,
    onClose: () => {
        console.log('Корзина закрыта');
    }
});

// Позже закрыть
window.waTheme.offcanvasAPI.close('cart-summary');

События

Offcanvas поддерживает события HSOverlay:

const offcanvasEl = document.querySelector('#myCustomOffcanvas');

offcanvasEl.addEventListener('open.hs.overlay', () => {
    console.log('Панель открыта');
});

offcanvasEl.addEventListener('close.hs.overlay', () => {
    console.log('Панель закрыта');
});