Как перехватить нажатие кнопки в HTML-поле 1С и открыть форму объекта?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов в 1С с использованием Поля HTML документа программисты часто сталкиваются с задачей обратной связи: как при клике на элемент внутри HTML-страницы заставить 1С выполнить какое-то действие, например, открыть форму справочника или регистра? Особенно это актуально, когда интерфейс отрисовывается динамически или используется элемент canvas.

В этой статье мы подробно проанализируем ситуацию, разберем классический способ решения через DOM-дерево и рассмотрим современные возможности платформы 1С для работы с движком WebKit.

Разбор проблемы: Почему 1С «не видит» клики в JS?

Когда мы загружаем HTML-страницу в форму 1С, она живет в контексте встроенного браузера (в современных версиях это WebKit/Chromium). События JavaScript (такие как onclick) исполняются внутри этого браузера и по умолчанию не «пробрасываются» в код 1С. Для того чтобы платформа отреагировала на действие пользователя, нам нужно создать «мостик» между миром JavaScript и миром 1С.

Рассмотрим ситуацию, когда кнопки отрисованы на canvas. Поскольку canvas — это фактически единая картинка для браузера, отдельные «кнопки» на нем не являются объектами DOM. Нам нужно вычислить координаты клика в JS и передать сигнал в 1С.

Способ 1. Использование невидимого элемента (классический «костыльный» метод)

Проанализируем решение, которое часто применялось в старых версиях платформы и остается рабочим сегодня. Суть метода заключается в использовании скрытого HTML-элемента (например, div или input), данные в котором меняются скриптом, после чего программно вызывается событие клика, перехватываемое в 1С.

Разберем по шагам реализацию этого метода. Сначала подготовим HTML-макет со скриптом:


<html>
<head>
    <script>
        function notify1C(data) {
            // Находим наш скрытый элемент
            var hiddenField = document.getElementById("TransferField");
            // Записываем в него нужные данные (например, фамилию или ID)
            hiddenField.innerHTML = data;
            // Имитируем клик по элементу, чтобы сработало событие в 1С
            hiddenField.onclick();
        }
    </script>
</head>
<body>
    <!-- Скрытый элемент для передачи данных -->
    <div id="TransferField" hidden></div>
    
    <p>Кликните по фамилии для открытия записи:</p>
    <button onclick="notify1C('Иванов')">Иванов</button>
    <button onclick="notify1C('Петров')">Петров</button>
</body>
</html>

Теперь проанализируем код на стороне 1С. В форме нам необходимо создать реквизит типа Строка, связанный с полем HTML-документа, и назначить обработчик события ПриНажатии.


&НаКлиенте
Процедура ПолеHTMLПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
    
    // Получаем доступ к нашему скрытому элементу через DOM
    ЭлементHTML = ДанныеСобытия.Document.getElementById("TransferField");
    ЗначениеИзJS = ЭлементHTML.innerHTML;
    
    Если ЗначениеИзJS = "" Тогда
        Возврат;
    КонецЕсли;
    
    // Выполняем логику 1С
    Если ЗначениеИзJS = "Иванов" Тогда
        Сообщить("Открываем форму для: " + ЗначениеИзJS);
        // Здесь вызываем ОткрытьФорму() для регистра сведений
    КонецЕсли;
    
    // Очищаем поле, чтобы исключить повторные срабатывания
    ЭлементHTML.innerHTML = "";
    
КонецПроцедуры

Важный нюанс: Чтобы этот метод работал стабильно, в параметре ДанныеСобытия мы получаем объект Document, который позволяет напрямую взаимодействовать с объектной моделью страницы.

Способ 2. Современный механизм window.external.message (для 1С 8.3.14+)

Выясним причину, по которой первый способ считается устаревшим. В новых релизах платформы (начиная с 8.3.14) при использовании WebKit появился штатный механизм взаимодействия. Теперь нам не нужно создавать невидимые поля.

Рассмотрим, как это работает. В JavaScript мы вызываем специальный метод window.external.message(). Этот метод отправляет строку напрямую в платформу 1С.

Пример JS-кода:


function onButtonClick(employeeName) {
    // Отправляем сообщение в 1С
    window.external.message(employeeName);
}

В 1С для Поля HTML документа необходимо создать обработчик события ВнешнееСобытие (или ОбработкаСобытия в зависимости от контекста). В этом событии параметр Сообщение будет содержать именно ту строку, которую мы передали из JavaScript.

Преимущества этого метода:

  1. Высокая скорость: Нет необходимости манипулировать DOM-деревом.
  2. Надежность: Прямая передача данных через движок WebKit.
  3. Чистота кода: Отсутствие «мусорных» скрытых элементов на странице.

Способ 3. Перехват через v8:// и ПередПереходом

Проанализируем еще одну интересную возможность — использование протокола v8://. Мы можем оформить нажатие кнопки как переход по ссылке с произвольными параметрами.

В JavaScript пишем:

window.location.href = "v8://openCard?lastName=Ivanov";

В 1С используем событие поля HTML ПередПереходом (или ПриНажатии):


&НаКлиенте
Процедура ПолеHTMLПередПереходом(Элемент, URL, СтандартнаяОбработка)
    Если Найти(URL, "v8://openCard") > 0 Тогда
        // Отменяем стандартный переход браузера
        СтандартнаяОбработка = Ложь;
        
        // Парсим параметры из URL и открываем форму
        Параметры = РазобратьURL(URL); 
        ОткрытьФормуЗаписи(Параметры.lastName);
    КонецЕсли;
КонецПроцедуры

Работа с Canvas и сложными данными

Если вы используете canvas, то, как мы выяснили ранее, платформа не увидит клики внутри него. Выходом будет использование addEventListener в JS для самого холста. После вычисления координат и определения объекта, по которому кликнули, используйте JSON.stringify() для упаковки данных.

Рассмотрим пример передачи сложной структуры:


// В JavaScript
let data = { action: "open", id: 123, type: "Register" };
window.external.message(JSON.stringify(data));

В 1С мы принимаем эту строку и десериализуем её:


&НаКлиенте
Процедура ОбработкаСообщенияИзJS(Сообщение)
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(Сообщение);
    Данные = ПрочитатьJSON(Чтение);
    
    Если Данные.action = "open" Тогда
        // Логика открытия формы по ID
    КонецЕсли;
КонецПроцедуры

Подведем итог: Для старых конфигураций и обеспечения максимальной совместимости можно использовать метод со скрытым div. Однако для современных решений на базе 1С 8.3.14+ настоятельно рекомендуем использовать window.external.message. Это обеспечит стабильную работу интерфейса и упростит поддержку программного кода.

← На главную