Дизайнер нарисовал аккуратную кнопку «Написать нам» в шапке, а Битрикс24 предлагает круглый виджет в углу экрана. Задача — связать одно с другим.
Способов ровно два, и разница между ними принципиальна: официальный API виджета и клик по его внутренней вёрстке. Разберём оба и почему второй способ — временное решение, даже когда работает.
Задача
Открыть виджет Битрикс24 (чат, callback, CRM-форма) по клику на кастомную кнопку в дизайне сайта, а не на стандартную круглую кнопку в углу.
Открытие онлайн-чата
Код ниже опирается на внутренние CSS-классы виджета (.b24-widget-button-openline_livechat и подобные). Это вёрстка стороннего продукта: она не документирована, не является публичным контрактом и меняется при обновлении виджета — а обновляется он сам, без вашего участия.
Сломается это тихо: кнопка на сайте останется, клик перестанет что-либо делать, а document.querySelector вернёт null, который код молча проигнорирует. Обнаружит проблему клиент, который не смог написать в чат.
Если задача решается официальным API (BX24 / b24widget предоставляют методы открытия чата и форм) — используйте его. Приём с кликом по вёрстке уместен как временное решение, но тогда предусмотрите заметность отказа: если селектор не нашёлся, покажите обычную ссылку или почту вместо неработающей кнопки.
// Функция открытия чата
function openB24Chat() {
// Вариант 1: Через trigger jQuery
if (window.jQuery) {
jQuery('.b24-widget-button-openline_livechat .b24-widget-button-social-tooltip')
.trigger('click');
}
// Вариант 2: Через нативный click
const chatBtn = document.querySelector(
'.b24-widget-button-openline_livechat .b24-widget-button-social-tooltip'
);
if (chatBtn) {
chatBtn.click();
}
}HTML-кнопка:
<button class="btn btn-primary" onclick="openB24Chat()">
<svg><!-- иконка чата --></svg>
Написать менеджеру
</button>
<!-- Или ссылка -->
<a href="javascript:void(0)" onclick="openB24Chat()" class="chat-link">
Онлайн-консультант
</a>Открытие формы обратного звонка
function openB24Callback() {
const callbackBtn = document.querySelector(
'.b24-widget-button-callback .b24-widget-button-social-tooltip'
);
if (callbackBtn) {
callbackBtn.click();
}
}<button class="callback-btn" onclick="openB24Callback()">
📞 Заказать звонок
</button>Универсальный класс для виджетов
class B24WidgetController {
constructor() {
this.selectors = {
chat: '.b24-widget-button-openline_livechat .b24-widget-button-social-tooltip',
callback: '.b24-widget-button-callback .b24-widget-button-social-tooltip',
// Добавьте другие типы виджетов
};
this.isWidgetLoaded = false;
this.checkWidgetInterval = null;
}
/**
* Ожидание загрузки виджета
*/
waitForWidget(callback, timeout = 10000) {
const startTime = Date.now();
const check = () => {
const widget = document.querySelector('.b24-widget-button-wrapper');
if (widget) {
this.isWidgetLoaded = true;
callback();
return;
}
if (Date.now() - startTime < timeout) {
setTimeout(check, 100);
} else {
console.warn('B24 widget not loaded within timeout');
}
};
check();
}
/**
* Открытие чата
*/
openChat() {
this.triggerWidget('chat');
}
/**
* Открытие callback
*/
openCallback() {
this.triggerWidget('callback');
}
/**
* Универсальный триггер
*/
triggerWidget(type) {
const selector = this.selectors[type];
if (!selector) {
console.error(`Unknown widget type: ${type}`);
return;
}
const button = document.querySelector(selector);
if (button) {
button.click();
} else {
// Виджет ещё не загружен — ждём
this.waitForWidget(() => {
const btn = document.querySelector(selector);
if (btn) btn.click();
});
}
}
/**
* Скрытие стандартной кнопки
*/
hideDefaultButton() {
const style = document.createElement('style');
style.textContent = `
.b24-widget-button-wrapper {
display: none !important;
}
`;
document.head.appendChild(style);
}
/**
* Показ только при наведении
*/
showOnHover(targetSelector) {
const target = document.querySelector(targetSelector);
const widget = document.querySelector('.b24-widget-button-wrapper');
if (!target || !widget) return;
widget.style.opacity = '0';
widget.style.transition = 'opacity 0.3s';
target.addEventListener('mouseenter', () => {
widget.style.opacity = '1';
});
target.addEventListener('mouseleave', () => {
widget.style.opacity = '0';
});
}
}
// Глобальный экземпляр
window.b24Widget = new B24WidgetController();Использование
<!-- Кнопка чата -->
<button onclick="b24Widget.openChat()" class="btn-chat">
Чат с менеджером
</button>
<!-- Кнопка callback -->
<button onclick="b24Widget.openCallback()" class="btn-callback">
Перезвоните мне
</button>
<!-- Скрыть стандартную кнопку -->
<script>
document.addEventListener('DOMContentLoaded', function() {
b24Widget.hideDefaultButton();
});
</script>Открытие CRM-формы
Для CRM-форм Битрикс24 используется другой API:
// Открытие встроенной CRM-формы по ID
function openB24CrmForm(formId) {
if (typeof BX24 !== 'undefined' && BX24.openApplication) {
// Для приложений
BX24.openApplication({
bx24_form_id: formId
});
} else if (typeof b24form !== 'undefined') {
// Для виджета на сайте
b24form({ id: formId, show: true });
}
}<button onclick="openB24CrmForm('form_1_abc123')">
Оставить заявку
</button>Интеграция с модальными окнами
// Открытие чата при закрытии модалки
document.querySelector('.modal-close').addEventListener('click', function() {
// Предлагаем помощь
setTimeout(() => {
if (confirm('Остались вопросы? Напишите нам в чат!')) {
b24Widget.openChat();
}
}, 500);
});
// Callback после заполнения формы
document.querySelector('#contact-form').addEventListener('submit', function(e) {
e.preventDefault();
// Отправляем форму...
// Открываем чат
alert('Спасибо! Менеджер свяжется с вами. Или напишите нам прямо сейчас:');
b24Widget.openChat();
});Стилизация кастомных кнопок
.btn-chat,
.btn-callback {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.75rem 1.5rem;
border: none;
border-radius: 2rem;
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-chat {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.btn-chat:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
.btn-callback {
background: #10b981;
color: white;
}
.btn-callback:hover {
background: #059669;
}
/* Иконки */
.btn-chat::before {
content: '💬';
}
.btn-callback::before {
content: '📞';
}Отслеживание событий виджета
// Слушаем события виджета (если доступен API)
if (typeof Bitrix24Widget !== 'undefined') {
Bitrix24Widget.on('form_submit', function(data) {
// Отправка в аналитику
if (window.ym) {
ym(YANDEX_METRIKA_ID, 'reachGoal', 'b24_form_submit');
}
if (window.gtag) {
gtag('event', 'form_submit', {
'event_category': 'b24_widget',
'event_label': data.formId
});
}
});
}Итоги
Предпочитайте официальный API вёрстке. Селекторы внутренних классов работают до ближайшего обновления виджета и ломаются молча.
Учитывайте асинхронную загрузку. Виджет подгружается после основной страницы, и пользователь вполне успевает нажать кнопку раньше. Ожидание готовности обязательно — иначе первый клик просто ничего не делает, а второй работает, и воспроизвести это в отладке сложно.
Предусмотрите поведение при отказе. Виджет может не загрузиться: блокировщик рекламы, недоступность домена, отключённый JavaScript. Кнопка, которая в этом случае просто не реагирует, хуже отсутствующей — пользователь считает, что связаться с вами нельзя. Резервный вариант в виде обычной ссылки на почту или телефон решает вопрос.
Если скрываете стандартную кнопку виджета через CSS — проверьте на мобильных. На узких экранах разметка виджета отличается, и селектор, скрывающий кнопку на десктопе, может её не поймать, оставив на телефоне две точки входа в чат. Проверять нужно на реальном устройстве: эмуляция в браузере воспроизводит не всё.
Комментарии
Система комментариев скоро будет подключена. А пока вы можете написать мне в Telegram или на email.