BX.fireEvent()
— маленькая, но крайне полезная функция ядра Bitrix. Она берёт на себя всю кросс-браузерную «грязь» и позволяет вызвать любое DOM-событие так, будто пользователь действительно кликнул мышью или нажал клавишу. Ниже — подробное руководство с рабочими примерами без внешних ссылок и без «потухших» API вроде BX.eventCancelable
.

1. Сигнатура
BX.fireEvent(
/** @type {HTMLElement | Document | Window} */ node,
/** @type {string} */ eventName
);
- node — DOM-узел,
document
илиwindow
, на котором надо «зажечь» событие. - eventName — строка без приставки
on
:"click"
,"submit"
,"focusin"
и т. д.
Внутри функция сама решит, использовать dispatchEvent
, старый fireEvent
IE или создать объект Event
.
2. Когда BX.fireEvent
действительно нужен
Ситуация | Почему простого кода мало | Решение |
---|---|---|
Вы изменили значение <input> из скрипта, а над полем висит валидатор сторонней библиотеки, «слушающий» change |
Прямое присвоение value не сгенерирует change |
BX.fireEvent(input, 'change'); |
Нужно запустить цепочку внутренних обработчиков Bitrix (навешаны через BX.bind ) из end-to-end теста |
Чистый dispatchEvent зачастую ломается на IE 11 и старых Chromium |
BX.fireEvent(btn, 'click'); |
Нужно обновить UI-виджет, который подписан на keyup , при программной смене фокуса |
Сомнительно вызывать обработчик напрямую | BX.fireEvent(node, 'keyup'); |
3. Простые примеры
3.1 Виртуальный клик по кнопке
<button id="demo-btn">Нажми виртуально</button>
<script>
BX.ready(() => {
const button = BX('demo-btn');
BX.bind(button, 'click', () => {
alert('Обработчик сработал!');
});
// эмулируем через секунду
setTimeout(() => BX.fireEvent(button, 'click'), 1000);
});
</script>
Через 1 с видим alert
, словно пользователь кликнул.
3.2 Изменение поля ввода и уведомление всех слушателей
<input id="phone" placeholder="+7(___)___-__-__">
<script>
BX.ready(() => {
const field = BX('phone');
BX.bind(field, 'change', ev => {
console.log('Новое значение:', ev.target.value);
});
// Меняем программно
field.value = '+7 900 111-22-33';
BX.fireEvent(field, 'change');
});
</script>
4. Расширенные паттерны
4.1 Автосохранение формы без BX.eventCancelable
Реализуем авто-submit при наборе текста, использовав дебаунс и классический preventDefault
.
<form id="profile-form">
<label>Имя <input name="NAME" required></label>
<label>Email <input name="EMAIL" required type="email"></label>
<button type="submit">Сохранить</button>
<span id="save-status"></span>
</form>
<script>
BX.ready(() => {
const form = BX('profile-form');
const status = BX('save-status');
// простенькая обёртка-дебаунс (чтобы не подключать lodash)
const debounce = (fn, ms = 300) => {
let t; return (...args) => {
clearTimeout(t); t = setTimeout(() => fn(...args), ms);
};
};
// Слушаем любые изменения внутри формы
BX.bindDelegate(
form,
'input',
{ tag: /input|textarea|select/i },
debounce(() => BX.fireEvent(form, 'submit'), 400)
);
// Обрабатываем submit (настоящий и виртуальный)
BX.bind(form, 'submit', async e => {
BX.PreventDefault(e); // кросс-браузерное preventDefault
status.textContent = 'Сохраняю…';
status.style.color = '#666';
// собираем данные и «шлём» (заглушка)
const data = BX.ajax.prepareForm(form).data;
await new Promise(r => setTimeout(r, 700)); // имитация AJAX
status.textContent = '✓ Сохранено';
status.style.color = 'green';
});
});
</script>
Особенности:
BX.fireEvent(form, 'submit')
вызывается из дебаунса при любом вводе — так мы используем единственную точку сохранения.- Никаких «потухших» API: вместо
BX.eventCancelable
— обычныйBX.PreventDefault(e)
.
4.2 Интеграция со сторонним jQuery-плагином
Допустим, на странице уже подключён jQuery-datepicker, который реагирует на focus
. Создадим дату программно:
<input id="date" data-toggle="datepicker">
<script>
BX.ready(() => {
$('#date').datepicker(); // инициализация jQuery-UI
const input = BX('date');
input.value = '31.12.2025';
BX.fireEvent(input, 'focus'); // datepicker отреагирует и откроется
});
</script>
4.3 Автотест: проверяем, что таб переключается по нажатию клавиши
test('Tab переключается на стрелку вправо', () => {
const tab = document.querySelector('[data-tab="files"]');
BX.fireEvent(tab, 'keydown'); // эмулируем нажатие
expect(tab.classList.contains('active')).toBe(true);
});
5. BX.onCustomEvent
vs BX.fireEvent
Требуется | Использовать |
---|---|
Оповестить только тех, кто подписан через BX.addCustomEvent |
BX.onCustomEvent(target, 'MyEvent', [args]) |
Сымитировать родное DOM-событие, чтобы отреагировали и старые скрипты, и сторонние библиотеки | BX.fireEvent(node, 'click') |
Комбинировать можно: после AJAX-обновления корзины отправить BX.onCustomEvent(window, 'BasketUpdated')
, а для совместимости «поджечь» change
на суммарном блоке.
6. Подводные камни
event.isTrusted
— у синтетических событий всегдаfalse
. Некоторые либы (например, React 17+) могут это проверять.stopPropagation
остаётся рабочим. Если первый обработчик его вызовет, остальные не получат событие, как и в реальной жизни.- Производительность. Не запускайте сотни
fireEvent
подряд — вынесите вrequestAnimationFrame
или таймер. - Формы. Чтобы обработчики реально отработали, лучше эмулировать
submit
на<form>
, а неclick
на кнопке. - Старые браузеры. В IE 9–11
BX.fireEvent
используетdocument.createEvent('Event')
, так что кастомные типы ('my-event'
) не всплывут — там используйтеBX.onCustomEvent
.
7. Итог
BX.fireEvent
— надёжный способ единообразно эмулировать DOM-события в экосистеме 1С-Битрикс.- Используйте его точечно, когда нужно запустить чужие слушатели, не переписывая легаси-код.
- Не полагайтесь на не-документированные обёртки (
BX.eventCancelable
и т. д.) — делайтеBX.PreventDefault(e)
вручную или напишите свой маленький helper. - Комбинируйте
BX.fireEvent
сBX.onCustomEvent
, чтобы покрыть сразу оба уровня — DOM и «битриксовые» кастомы.
Теперь вы вооружены и готовы безопасно «поджигать» события, экономя время на кросс-браузерных полифилах и интеграциях. Пусть код будет чище, а интерфейсы — отзывчивее!