При разработке интерфейсов в 1С с использованием Поля HTML документа программисты часто сталкиваются с задачей обратной связи: как при клике на элемент внутри HTML-страницы заставить 1С выполнить какое-то действие, например, открыть форму справочника или регистра? Особенно это актуально, когда интерфейс отрисовывается динамически или используется элемент canvas.
В этой статье мы подробно проанализируем ситуацию, разберем классический способ решения через DOM-дерево и рассмотрим современные возможности платформы 1С для работы с движком WebKit.
Когда мы загружаем HTML-страницу в форму 1С, она живет в контексте встроенного браузера (в современных версиях это WebKit/Chromium). События JavaScript (такие как onclick) исполняются внутри этого браузера и по умолчанию не «пробрасываются» в код 1С. Для того чтобы платформа отреагировала на действие пользователя, нам нужно создать «мостик» между миром JavaScript и миром 1С.
Рассмотрим ситуацию, когда кнопки отрисованы на canvas. Поскольку canvas — это фактически единая картинка для браузера, отдельные «кнопки» на нем не являются объектами DOM. Нам нужно вычислить координаты клика в JS и передать сигнал в 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, который позволяет напрямую взаимодействовать с объектной моделью страницы.
Выясним причину, по которой первый способ считается устаревшим. В новых релизах платформы (начиная с 8.3.14) при использовании WebKit появился штатный механизм взаимодействия. Теперь нам не нужно создавать невидимые поля.
Рассмотрим, как это работает. В JavaScript мы вызываем специальный метод window.external.message(). Этот метод отправляет строку напрямую в платформу 1С.
Пример JS-кода:
function onButtonClick(employeeName) {
// Отправляем сообщение в 1С
window.external.message(employeeName);
}
В 1С для Поля HTML документа необходимо создать обработчик события ВнешнееСобытие (или ОбработкаСобытия в зависимости от контекста). В этом событии параметр Сообщение будет содержать именно ту строку, которую мы передали из JavaScript.
Преимущества этого метода:
Проанализируем еще одну интересную возможность — использование протокола v8://. Мы можем оформить нажатие кнопки как переход по ссылке с произвольными параметрами.
В JavaScript пишем:
window.location.href = "v8://openCard?lastName=Ivanov";
В 1С используем событие поля HTML ПередПереходом (или ПриНажатии):
&НаКлиенте
Процедура ПолеHTMLПередПереходом(Элемент, URL, СтандартнаяОбработка)
Если Найти(URL, "v8://openCard") > 0 Тогда
// Отменяем стандартный переход браузера
СтандартнаяОбработка = Ложь;
// Парсим параметры из URL и открываем форму
Параметры = РазобратьURL(URL);
ОткрытьФормуЗаписи(Параметры.lastName);
КонецЕсли;
КонецПроцедуры
Если вы используете 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. Это обеспечит стабильную работу интерфейса и упростит поддержку программного кода.