Как адаптировать работу с Полем HTML документа при переходе на WebKit в 1С 8.3.14?

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

Начиная с версии платформы 1С:Предприятие 8.3.14.1565, разработчики столкнулись с серьезным архитектурным изменением. На операционной системе Windows платформа отказалась от использования устаревшего COM-объекта Internet Explorer для рендеринга HTML и перешла на современный кроссплатформенный движок WebKit (который ранее уже использовался в клиентах под Linux и macOS). С одной стороны, это сделало отображение веб-страниц более быстрым и соответствующим современным стандартам HTML5/CSS3. С другой стороны, старый код, написанный с расчетом на COM-взаимодействие с Internet Explorer, перестал работать.

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

Изменение архитектуры: COMОбъект против ВнешнегоОбъекта

Прежде чем переходить к написанию кода, проанализируем ключевое изменение в типах данных. Ранее в свойстве Документ объекта ПолеHTMLДокумента возвращался полноценный COMОбъект (ActiveX-обертка над Internet Explorer). Это позволяло напрямую обращаться к свойствам и методам объектной модели документа (DOM), используя привычный синтаксис 1С через точку.

После перехода на WebKit тип свойства Документ изменился на ВнешнийОбъект. Платформа 1С больше не может транслировать произвольные вызовы методов JavaScript напрямую через интерфейсы COM. Именно поэтому прямые обращения к функциям вроде getElementById приводят к ошибкам времени выполнения.

Решение 1. Кроссплатформенный доступ к объекту Window (parentWindow vs defaultView)

Первая проблема, с которой сталкиваются разработчики при поддержке старого кода — это получение глобального объекта окна браузера. В Internet Explorer для этого использовалось свойство parentWindow, в то время как во всех современных браузерах (включаю WebKit) стандартом является defaultView.

Посмотрим на пример универсального кода, который позволит вашей обработке или форме корректно работать как на старых релизах платформы (с IE), так и на новых (с WebKit):


Если Элементы.ПолеHTMLДокумента.Документ.parentWindow = Неопределено Тогда
    // Вариант для WebKit (Chrome/Safari-совместимый движок)
    ОкноБраузера = Элементы.ПолеHTMLДокумента.Документ.defaultView;
Иначе
    // Вариант для старого Internet Explorer (COM-объект)
    ОкноБраузера = Элементы.ПолеHTMLДокумента.Документ.parentWindow;
КонецЕсли;

Использование этого условия гарантирует, что программа не завершится аварийно при попытке получить контекст окна.

Решение 2. Обход ошибки "Метод не обнаружен" при вызове getElementById

Вызов конструкции Элемент.Документ.getElementById("ИмяЭлемента") напрямую из встроенного языка 1С в режиме WebKit больше не поддерживается. Чтобы обойти это ограничение, нам необходимо перенести логику поиска элементов на сторону самого HTML-документа, создав там простую JavaScript-функцию.

Рассмотрим, как это сделать по шагам:

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

<script>
    function getElementValueById(elementId) {
        var elem = document.getElementById(elementId);
        return elem ? elem.value : "";
    }
</script>
  1. После этого во встроенном языке 1С вы можете легко вызывать эту функцию через объект defaultView:

// Получаем доступ к окну WebKit
ОкноБраузера = Элементы.ПолеHTMLДокумента.Документ.defaultView;

// Вызываем нашу JS-функцию напрямую из 1С
ЗначениеПоля = ОкноБраузера.getElementValueById("MyInputFieldID");

Через объект defaultView платформа 1С успешно вызывает любые глобальные JavaScript-функции, объявленные в контексте загруженной веб-страницы. Это открывает нам путь к созданию удобного API-посредника между 1С и веб-интерфейсом.

Решение 3. Реализация аналога метода eval для выполнения произвольного JS-кода

В старых версиях на базе Internet Explorer разработчики часто использовали метод eval() напрямую из 1С для динамического выполнения кода на веб-странице. В WebKit прямой вызов eval из 1С заблокирован из соображений безопасности. Тем не менее, нам никто не мешает написать собственную функцию-обертку.

Давайте выясним, как реализовать универсальный выполнитель JavaScript-кода:

  1. Добавим на HTML-страницу следующую функцию:

<script type="text/javascript">
    function execJavaScript(scriptText) {
        return eval(scriptText);
    }
</script>
  1. Теперь из встроенного языка 1С мы можем передавать абсолютно любой JavaScript-код в виде строки для его мгновенного выполнения в контексте страницы:

// Пример вызова простого сообщения alert
Элементы.ПолеHTMLДокумента.Документ.defaultView.execJavaScript("alert('Успешно запущено из 1С!');");

Решение 4. Вызов системных функций отправки формы (__doPostBack и setTimeout)

Довольно часто при интеграции с внешними сайтами (например, при парсинге или автоматическом заполнении форм логина/пароля) требуется эмулировать действия пользователя. Например, запустить стандартный ASP.NET скрипт отправки формы: __doPostBack.

Разберем ситуацию, когда вам нужно выполнить следующий код:

javascript:setTimeout('__doPostBack(\'ctl00$CCAuth1$persTypeDrop\',\'\')', 0)

С использованием WebKit мы можем реализовать это двумя эффективными способами:

Способ А. Прямой вызов функции страницы (если функция объявлена глобально)

Если метод __doPostBack присутствует в глобальной области видимости window, мы можем вызвать его напрямую, передав параметры из 1С. В большинстве случаев задержка через setTimeout не является обязательной:


Элементы.ПолеHTMLДокумента.Документ.defaultView.__doPostBack("ctl00$CCAuth1$persTypeDrop", "");

Способ Б. Использование нашей функции-обертки execJavaScript

Если для логики сайта критически важно запустить код именно через асинхронный таймаут, мы конструируем строку вызова и передаем её в нашу функцию-посредник:


JSКод = "setTimeout(function() { __doPostBack('ctl00$CCAuth1$persTypeDrop', ''); }, 0);";
Элементы.ПолеHTMLДокумента.Документ.defaultView.execJavaScript(JSКод);

Другие известные нюансы работы WebKit в 1С

Помимо работы с DOM и выполнения скриптов, при миграции кода на движок WebKit следует учитывать еще несколько важных ограничений:

  1. Работа с data-атрибутами (dataset): Обращение к свойствам элементов через element.dataset из кода 1С напрямую не поддерживается. Для чтения и записи таких атрибутов всегда используйте JS-методы getAttribute("data-...") и setAttribute("data-...", value) через функции-обертки.
  2. Определение позиции прокрутки (скролла): Получить точные координаты прокрутки страницы напрямую из 1С не удастся. Напишите простую функцию на стороне JS, возвращающую window.pageYOffset или document.documentElement.scrollTop.
  3. Буфер обмена и горячие клавиши: В некоторых ранних версиях платформы 8.3.14 наблюдались сложности с обработкой стандартных сочетаний клавиш (таких как Ctrl+C, Ctrl+V) внутри полей ввода HTML-документа. Если вы разрабатываете сложный WYSIWYG-редактор, будьте готовы перехватывать события клавиатуры средствами JavaScript на уровне самого документа.

Резюмируем: Переход на движок WebKit лишил нас возможности использовать "грязные" прямые обращения к COM-объектам Internet Explorer, однако он предоставил более быструю и стабильную среду выполнения. Использование JavaScript-функций в качестве интерфейса взаимодействия между 1С и страницей (через объект defaultView) является наиболее надежным, чистым и кроссплатформенным решением.

← На главную