Как вызвать JavaScript функции из управляемой формы 1С?

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

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

Причины возникновения ошибки «Метод объекта не обнаружен»

Прежде чем переходить к коду, проанализируем ситуацию, когда 1С выдает ошибку при попытке вызова функции. Чаще всего это происходит по двум причинам:

  1. Неготовность документа: Вызов функции происходит в обработчике ПриСозданииНаСервере или слишком рано на клиенте, когда DOM-дерево страницы еще не загружено, и скрипты не инициализированы.
  2. Различие движков (IE vs WebKit): В старых версиях 1С использовался движок Internet Explorer (MSHTML), где доступ шел через parentWindow. В новых версиях (начиная с 8.3.14) используется WebKit/Chromium, где структура обращения изменилась.
  3. Регистр имен: JavaScript чувствителен к регистру. Если функция в JS названа myFunction, обращение из 1С должно быть точно таким же.

Метод 1: Прямой вызов через defaultView (для современных платформ)

Рассмотрим наиболее актуальный способ для последних релизов платформы 1С. Вместо устаревшего parentWindow мы будем использовать свойство defaultView. Это позволяет обращаться к глобальной области видимости окна браузера напрямую.

Для начала создадим простейшую HTML-страницу с функцией, которую мы будем вызывать. Мы можем хранить этот текст в макете или формировать программно:


<html>
<head>
    <script>
        function ShowMessage(text) {
            alert("Сообщение из 1С: " + text);
            return true;
        }
    </script>
</head>
<body>
    <h1>Интерактивная страница</h1>
</body>
</html>

Теперь разберем, как правильно вызвать эту функцию со стороны 1С. Важно дождаться события ДокументСформирован, чтобы гарантировать наличие функции в памяти браузера.


&НаКлиенте
Перем ДокументГотов;

&НаКлиенте
Процедура ПолеHTMLДокументСформирован(Элемент)
    ДокументГотов = Истина;
КонецПроцедуры

&НаКлиенте
Процедура ВызватьJSФункцию(Команда)
    Если Не ДокументГотов Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем окно документа
    ОкноJS = Элементы.ПолеHTML.Документ.defaultView;
    
    // Вызываем функцию напрямую
    Попытка
        ОкноJS.ShowMessage("Привет из 1С!");
    Исключение
        Сообщить("Не удалось вызвать функцию: " + ОписаниеОшибки());
    КонецПопытки;
КонецПроцедуры

Метод 2: Передача сложных структур (Массивов и Объектов)

Одной из главных проблем, обсуждаемых программистами, является передача массивов. Напрямую передать объект Массив из 1С в JavaScript не всегда получается корректно из-за разницы типов данных COM и JS. Проанализируем два способа решения этой задачи.

Вариант А: Использование метода Eval. Мы можем заставить JavaScript самостоятельно сконструировать массив из строки, которую мы подготовим в 1С. Это избавляет от проблем несовместимости типов.


&НаКлиенте
Процедура ПередатьМассивЧерезEval()
    // Формируем строку массива для JS
    СтрокаМассива = "[10, 20, 30, 40]";
    Элементы.ПолеHTML.Документ.defaultView.eval("ProcessArray(" + СтрокаМассива + ")");
КонецПроцедуры

Вариант Б: Использование JSON (Рекомендуемый). Это самый надежный и современный способ. Мы преобразуем массив или структуру 1С в строку JSON, передаем ее как один строковый параметр, а в JavaScript декодируем обратно в объект.

В 1С (код):


&НаКлиенте
Процедура ПередатьДанныеJSON()
    Данные = Новый Массив;
    Данные.Добавить("Параметр 1");
    Данные.Добавить(123);
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, Данные);
    СтрокаJSON = ЗаписьJSON.Закрыть();
    
    // Вызываем функцию, передавая JSON-строку
    Элементы.ПолеHTML.Документ.defaultView.DataHandler(СтрокаJSON);
КонецПроцедуры

В JavaScript (код на странице):


function DataHandler(jsonString) {
    var data = JSON.parse(jsonString);
    console.log(data[0]); // Выведет "Параметр 1"
    console.log(data[1]); // Выведет 123
}

Метод 3: Работа в Веб-клиенте

Если ваше приложение работает в веб-клиенте, прямой доступ к Элементы.ПолеHTML.Документ может быть закрыт из-за политики безопасности браузеров (Cross-Origin). В этом случае выясним, как обойти ограничение.

Рассмотрим механизм взаимодействия через навигацию. Вы можете изменить текст в поле HTML-документа или использовать событие ПриНажатии. Однако для вызова JS из 1С в веб-клиенте часто применяется методика «инъекции» кода через изменение реквизита, к которому привязан HTML-текст, но это требует перезагрузки страницы.

Для полноценного взаимодействия в веб-клиенте рекомендуется использовать библиотеку window.postMessage, если страница загружается с другого домена, или встраивать логику обработки событий в саму страницу, чтобы 1С лишь меняла данные, а скрипт JS реагировал на их изменение через MutationObserver.

Советы по отладке и стабильности

Проанализируем несколько важных моментов, которые помогут избежать ошибок при эксплуатации решения:

  1. Чувствительность к регистру: Всегда проверяйте, что имена функций в defaultView.ИмяФункции в 1С и function ИмяФункции в JS совпадают до символа.
  2. Ожидание загрузки: Никогда не вызывайте JS-функции сразу после установки текста в поле HTML. Всегда используйте флаг готовности, устанавливаемый в событии ДокументСформирован.
  3. Обработка исключений: Оборачивайте вызовы в блоки Попытка ... Исключение. Это позволит программе не «падать», если пользователь закроет форму в момент выполнения скрипта или если возникнет ошибка внутри самого JavaScript.
  4. Режим совместимости: Если вы используете старую платформу и движок IE, убедитесь, что в HTML-коде прописан мета-тег эмуляции браузера, иначе современные функции JS (например, JSON.parse) могут быть недоступны: <meta http-equiv="X-UA-Compatible" content="IE=edge" />

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

← На главную