При работе с компонентой Поле HTML документа в 1С:Предприятии разработчики часто сталкиваются с ситуацией, когда движок WebKit (пришедший на смену старому Internet Explorer/Trident) отказывается "видеть" функции JavaScript, объявленные в коде страницы. При этом переменные могут быть доступны, а вызов функции возвращает ошибку о том, что объект не найден. Рассмотрим подробнее, почему это происходит и как обеспечить стабильную работу скриптов в среде 1С.
Разберем ситуацию: вы объявили функцию внутри тега <script> в разделе head или body, но при попытке вызвать ее из кода 1С или через событие onload получаете ошибку. Основная причина кроется в различиях реализации глобальной области видимости и алгоритмах парсинга HTML-кода. В отличие от старого Internet Explorer, WebKit более строго изолирует контексты выполнения и может не успеть зарегистрировать функцию в глобальном объекте window к моменту вызова.
Проанализируем основные факторы, влияющие на видимость функций:
УстановитьТекст() передает данные в движок браузера, который начинает строить DOM-дерево и выполнять скрипты параллельно с основным потоком 1С.function name() {}, в некоторых версиях WebKit внутри 1С могут не попадать в пространство имен, доступное внешней среде (COM-объекту документа).Самый надежный способ сделать функцию "видимой" для 1С и других элементов страницы — это явное назначение ее свойством глобального объекта window. Это обходит механизмы оптимизации WebKit, которые могут скрывать локальные декларации функций.
Рассмотрим пример правильного объявления функции:
<script type="text/javascript">
// Вместо обычного объявления: function initialize() { ... }
// Используем прямое назначение в глобальный объект
window.initialize = function() {
console.log("Функция инициализирована");
return true;
};
</script>
Такой подход гарантирует, что функция будет записана в структуру window, и 1С сможет обратиться к ней через Документ.parentWindow.initialize() или современные методы выполнения JavaScript.
Часто проблема "невидимости" функции связана с тем, что код 1С пытается вызвать JavaScript до того, как страница полностью загрузилась. Использование проверки readyState == "complete" не всегда дает гарантию в WebKit, так как скрипты могут инициализироваться долями секунды позже.
Выясним, как правильно отлавливать момент готовности. В 1С для элемента формы Поле HTML документа существует специализированное событие ДокументСформирован (или ПриЗавершенииЗагрузки в управляемых формах). Рекомендуется вызывать инициализирующие функции JS именно в этом обработчике.
Пример реализации на стороне 1С (Обычные формы):
Процедура ЭлементыФормыЭксплорерДокументСформирован(Элемент)
// Документ полностью загружен движком WebKit
// Теперь можно безопасно вызывать JS-функции
Элемент.Документ.parentWindow.initialize();
КонецПроцедуры
Если вы используете Управляемые формы, воспользуйтесь методом ВыполнитьJavaScript:
&НаКлиенте
Процедура ПолеHTMLДокументаПриЗавершенииЗагрузки(Элемент)
Элементы.ПолеHTMLДокумента.ВыполнитьJavaScript("initialize();");
КонецПроцедуры
Для предотвращения конфликтов имен и обеспечения немедленного выполнения кода при загрузке скрипта, профессиональные разработчики используют самовызывающиеся функции. Это гарантирует, что весь ваш код будет выполнен в собственном контексте, а наружу (в window) попадут только нужные методы.
Проанализируем пример такой структуры:
(function() {
var internalVariable = "секретно";
window.myPublicFunction = function() {
alert("Вызвана функция из 1С. Внутренняя переменная: " + internalVariable);
};
// Инициализация карты или другого объекта
window.initializeMap = function(lat, lng) {
// Логика работы с Google Maps или OpenStreetMap
};
})();
Особое внимание стоит уделить тому, как 1С передает текст макета. Если вы используете ПолучитьОбщийМакет("Имя").ПолучитьТекст(), убедитесь, что макет сохранен в кодировке UTF-8 без BOM. Наличие метки порядка байтов (BOM) в начале строки может привести к тому, что WebKit интерпретирует первый тег <script> некорректно, из-за чего все функции внутри него станут недоступны.
Посмотрим, как можно очистить текст перед загрузкой, если возникают подозрения на проблемы с кодировкой:
ТекстМакета = ПолучитьОбщийМакет("GoogleMaps").ПолучитьТекст();
// В некоторых случаях полезно явно очистить DOM перед загрузкой
ЭлементыФормы.Эксплорер.УстановитьТекст("");
ЭлементыФормы.Эксплорер.УстановитьТекст(ТекстМакета);
Если функции по-прежнему не видны, разберем, как включить инструменты разработчика. В современных версиях 1С движок WebKit поддерживает удаленную отладку. Вы можете запустить 1С с ключом --remote-debugging-port=9222 и, открыв Chrome по адресу localhost:9222, увидеть консоль ошибок вашего Поля HTML документа. Это позволит мгновенно выяснить, произошла ли ошибка синтаксиса или функция действительно не была добавлена в глобальный контекст.
Важные выводы:
window.имяФункции = function... для гарантии видимости.УстановитьТекст(), используйте событие ДокументСформирован.ВыполнитьJavaScript().