Блог разработчика 1С-Битрикс

Эмуляция DOM-событий в 1С-Битрикс: секреты BX.fireEvent

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

Обработка событий. BX.fireEvent

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>

Особенности:

  1. BX.fireEvent(form, 'submit') вызывается из дебаунса при любом вводе — так мы используем единственную точку сохранения.
  2. Никаких «потухших» 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. Подводные камни

  1. event.isTrusted — у синтетических событий всегда false. Некоторые либы (например, React 17+) могут это проверять.
  2. stopPropagation остаётся рабочим. Если первый обработчик его вызовет, остальные не получат событие, как и в реальной жизни.
  3. Производительность. Не запускайте сотни fireEvent подряд — вынесите в requestAnimationFrame или таймер.
  4. Формы. Чтобы обработчики реально отработали, лучше эмулировать submit на <form>, а не click на кнопке.
  5. Старые браузеры. В 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 и «битриксовые» кастомы.

Теперь вы вооружены и готовы безопасно «поджигать» события, экономя время на кросс-браузерных полифилах и интеграциях. Пусть код будет чище, а интерфейсы — отзывчивее!

Теги:  BX.fireEvent, DOM-события, JavaScript, веб-разработка, эмуляция событий


Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Лечение сайтов от вирусов

восстановление сайта и подъем версии PHP

от 25 000 рублей
Лечение сайтов на решениях АСПРО и прочих.

* полный комплекс лечения проекта и закрытия дыр

Разработка интернет-магазина с готовой версткой

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.

Лендинг

от 3 дней

от 25 000 рублей

Разработка одностраничного сайта на платформе Битрикс

* стоимость зависит от наличия верстки, использования готового решения и т.д.