Розробка функціоналу зворотного відліку (таймер акції) 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка функціоналу зворотного відліку (таймер акції) 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка функціоналу зворотного відліку (таймер акції) 1С-Bitrix

Акція без дедлайну — це не акція, а постійна скидка. Таймер зворотного відліку створює ощущення обмеженості пропозиції й спонукає до рішення. Але в Bitrix немає штатного компонента зворотного відліку. Стандартний механізм скидок умить задавати період дії, а ось візуальний таймер на фронте — завдання для кастомної розробки. Розглянемо, як пов'язати таймер з реальними правилами скидок, щоб дата закінчення бралася з бази, а не була захардкожена в шаблоні.

Джерело даних: звідки брати дату закінчення

Таймер повинен показувати реальний строк акції, а не декоративні цифри. У Bitrix дати акцій зберігаються в кількох місцях:

Скидки каталогу — таблиця b_catalog_discount, поля ACTIVE_FROM й ACTIVE_TO. Отримуємо через \Bitrix\Catalog\DiscountTable::getList() з фільтром ACTIVE = Y й ACTIVE_TO > NOW().

Правила кошика — таблиця b_sale_discount, аналогічні поля. API: \Bitrix\Sale\Internals\DiscountTable::getList().

Властивість товара — можна створити властивість інфоблока PROMO_END_DATE типу «Дата/Час» й заповнювати вручну або автоматично при прив'язанні товара до акції.

Вибір джерела залежить від сценарію. Якщо таймер показується на карточці товара — зручна властивість або скидка каталогу. Якщо таймер глобальний (банер на головній) — правило кошика або окремий інфоблок акцій.

Архітектура компонента

Створюємо кастомний компонент local:sale.countdown в /local/components/local/sale.countdown/. Структура стандартна:

  • class.php — логіка вибірки даних.
  • templates/.default/template.php — HTML-розмітка.
  • templates/.default/script.js — JavaScript-логіка зворотного відліку.
  • .parameters.php — налаштовувані параметри компонента.

Параметри компонента:

Параметр Тип Описання
SOURCE_TYPE list Джерело: catalog_discount, sale_discount, iblock_property
DISCOUNT_ID int ID скидки (для catalog/sale)
IBLOCK_ID int ID інфоблока (для властивості товара)
ELEMENT_ID int ID елемента (для властивості товара)
PROPERTY_CODE string Код властивості з датою закінчення
DISPLAY_FORMAT list Формат: дні+години+хвилини+секунди або години+хвилини+секунди
ACTION_ON_EXPIRE list Дія при закінченні: приховати / показати повідомлення
CACHE_TIME int Час кешування

У class.php компонент отримує дату закінчення з обраного джерела й передає в шаблон timestamp:

$this->arResult['TIMESTAMP_END'] = (new \Bitrix\Main\Type\DateTime($endDate))->getTimestamp();

JavaScript: клієнтський відлік

Таймер працює повністю на клієнті. Серверна частина дає лише timestamp закінчення. Це принципово: AJAX-запити кожну секунду — навантаження без сенсу.

Ключовий момент — синхронізація часу. Клієнтські годинники можуть відрізнятися від серверних. Рішення: сервер передає не лише TIMESTAMP_END, але й TIMESTAMP_SERVER — поточний серверний час. JavaScript обчислює дельту й коректує відлік:

const serverNow = parseInt(container.dataset.serverTime);
const clientNow = Math.floor(Date.now() / 1000);
const drift = serverNow - clientNow;
const remaining = endTime - (Math.floor(Date.now() / 1000) + drift);

Оновлення DOM кожну секунду через setInterval — робочий варіант. Але для кількох таймерів на сторінці (листинг товарів з акціями) краще один requestAnimationFrame-цикл, який оновлює всі таймери за один прохід.

Дія при закінченні. Коли remaining <= 0, таймер не повинен просто зупинитися. Варіанти: приховати блок акції, замінити кнопку «Купити зі скидкою» на звичайну, показати повідомлення «Акція завершена». Для зміни кнопки — AJAX-запит до сервера для перевірки актуальності скидки й перерендер блока ціни.

Інтеграція з composite-кешем

Composite cache (автокомпозит) Bitrix кешує HTML-сторінку цілком. Таймер із серверним timestamp в HTML зламає кеш: кожний хіт буде унікальним.

Рішення — винести блок таймера в динамічну область. У template.php:

$frame = new \Bitrix\Main\Page\Frame('countdown_' . $this->arParams['DISCOUNT_ID']);
$frame->begin();
// HTML таймера
$frame->end();

Всередину динамічної області HTML оновлюється при кожному запиті, а решта сторінки отдається з кешу.

Альтернатива — не виводити timestamp в HTML взагалі. Замість цього зберігати його в окремому endpoint (/ajax/countdown.php), який JavaScript запитує один раз при завантаженні. Сторінка кешується повністю, дані таймера завантажуються окремо.

Прив'язка до правил скидок

Таймер сам по собі — лише візуал. Він повинен бути синхронізований з реальним правилом скидки. Якщо менеджер продовжив акцію в адміні — таймер має оновитися автоматично.

Для цього компонент при кожному скиданні кешу заново запитує ACTIVE_TO з таблиці скидок. Час кешування компонента ставимо невеликим — 300-600 секунд. Компроміс між актуальністю й навантаженням.

Додатково: обробник OnAfterCatalogDiscountUpdate / OnAfterSaleDiscountUpdate для скидання кешу компонента при зміні скидки. Теггований кеш (\Bitrix\Main\Data\TaggedCache) з тегом catalog_discount_{ID} розв'язує завдання точково.

Таймер на листингу товарів

Окреме завдання — показати таймери на сторінці каталогу, де 20-50 товарів. Кожен може мати свою акцію з окремим строком. Компонент викликається в циклі catalog.section — це кілька SQL-запитів.

Оптимізація: у class.php реалізуємо batch-режим. Компонент приймає масив ELEMENT_IDS, одним запитом отримує всі дати й повертає масив timestamp'ів. У шаблоні catalog.section — один виклик замість N.

Строки реалізації

Варіант Склад Строк
Простий таймер Один компонент, одна скидка, статичний endpoint 3-4 дні
Повне рішення Batch-режим, composite-сумісність, синхронізація з правилами, автоскидання кешу 7-10 днів