Вступление
Взаимодействие javascript и интерфейса 1С дает огромные возможности для реализации нестандартных функций. Раньше можно было напрямую вызывать функции JavaScript через DOM объект document Поля HTML документа. В современных браузерах эта возможность ушла. Более того, в веб-клиенте появляется тип ВнешнийОбъект, который вообще нигде не описан. На Инфостарте были предложения вызывать JavaScript через fireEvent, но это очень неудобно. Предлагаю свой вариант решения.
С чего все началось
Разбираться с HTML полем меня сподвигло большое количество задач, в которых была необходимость реализовать интерактивные карты с мониторингом, маршрутизацией и т.д. Поскольку встроенными средствами 1С сделать это невозможно, то раньше использовал ActiveX компоненту собственного изготовления. На обычных формах все работало приемлимо, не считая, что решение и рядом не стояло с открытыми фреймворками типа OpenLayers. После появления управляемых форм, была попытка встроить все тот же ActiveX в HTML документ и разместить его в поле. Решение работает, но в виду ужесточения политики безопасности Microsoft, требовало изменения настроек безопасности на каждом клиенте, что в конечном счете оказалось неприемлимым. Вот тогда мы и поставили перед собой задачу, прикрутить к управляемым формам карты на основе Web-движков (Яндекс.Карты, OpenLayers и прочие Tile ориентированные движки).
Вариант 1. Работает в толстом клиенте, работает в тонком клиенте, не работает в веб-клиенте
Суть метода заключается в получении свойства parentWindow элемента формы ПолеHTMLДокумента. Выглядит примерно так:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<script>
function HelloWorld(FormLink)
{
FormLink.WebMapJavascriptAction("Hello from outside!");
return "Hello world!";
}
</script>
</head>
<body>
</body>
</html>
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
WebКартаРеквизитФормыСтрока = Обработки.УНП_WEBКарта.ПолучитьМакет("HTMLМакет").ПолучитьТекст();
КонецПроцедуры
&НаКлиенте
Процедура WebКартаДокументСформирован(Элемент)
Сообщить(Элементы.WebКарта.Документ.parentWindow.HelloWorld(ЭтаФорма));
КонецПроцедуры
&НаКлиенте
Процедура WebMapJavascriptAction(Переменная) Экспорт
Сообщить(Переменная);
КонецПроцедуры
Все это прекрасно работает в толстом и тонком клиенте, но в веб-клиенте это работать не будет, так как в веб-клиенте у ПоляHTMLДокумента в свойстве Документ нет parentWindow.
Вариант 2. Работает в Толстом клиенте, тонком клиенте, веб-клиенте (проверено Chrome, IE, Edge)
Для реализации этого варианта необходимо немного исправить HTML макет. А именно:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
</head>
<body>
</body>
<script>
document.body.HelloWorld = function(FormLink)
{
FormLink.WebMapJavascriptAction("Hello from outside!");
return "Hello world!";
}
</script>
</html>
И небольшие правки в коде формы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ПовторноеСрабатывание = Ложь;
WebКартаРеквизитФормыСтрока = Обработки.УНП_WEBКарта.ПолучитьМакет("HTMLМакет").ПолучитьТекст();
КонецПроцедуры
&НаКлиенте
Процедура WebКартаДокументСформирован(Элемент)
Если Не ПовторноеСрабатывание Тогда // В некоторых случаях, при подключении дополнительных библиотек,
//событие может сработать повторно в уже загруженном документе
ОбъектBody = Неопределено;
Попытка
ОбъектBody = Элементы.WebКарта.Документ.parentWindow.document.body;
Исключение
КонецПопытки;
Если Не ЗначениеЗаполнено(ОбъектBody) Тогда
Попытка
ОбъектBody = Элементы.WebКарта.Документ.body;
Исключение
КонецПопытки;
КонецЕсли;
Если Не ЗначениеЗаполнено(ОбъектBody) Тогда
Сообщить("Что-то пошло не так");
Иначе
Сообщить(ОбъектBody.HelloWorld(ЭтаФорма));
КонецЕсли;
ПовторноеСрабатывание = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура WebMapJavascriptAction(Переменная) Экспорт
Сообщить(Переменная);
КонецПроцедуры
Таким образом для толстого и тонкого клиента мы оставляем все как и было, но для универсальности используем расширенный нами объект DOM body. В веб-клиенте элемент формы ПолеHTMLДокумента.Документ содержит тип ВнешнийОбъект, что на самом деле является COM реализацией элемента body по структуре DOM.
Теоретически можно написать функцию в body, которая вернет ссылку на window, и тогда можно вызывать глобальные функции.
Надеюсь кому-то поможет ;-)