Работа с Полем HTML-документа в 1С часто преподносит сюрпризы, особенно когда речь идет об автоматизации взаимодействия с современными веб-сайтами. Одной из типичных проблем является поиск элементов, имеющих несколько CSS-классов (например, динамические классы Angular ng-dirty ng-valid). Стандартные методы JavaScript, вызываемые через COM-объект 1С, могут вести себя непредсказуемо: либо не находить элементы, либо приводить к аварийному завершению работы (сворачиванию) платформы 1С. В этой статье мы подробно разберем, почему это происходит и как реализовать надежный поиск элементов.
Для начала проанализируем ситуацию с движком отображения. Поле HTML-документа в 1С (особенно в обычных формах) использует компоненту ActiveX Internet Explorer. Даже если у вас в системе установлен IE11 или Microsoft Edge, встроенный в 1С контроллер по умолчанию часто запускается в режиме эмуляции IE7 или IE8.
Рассмотрим основные технические нюансы:
"class1 class2", браузер пытается найти элемент, у которого атрибут class в точности совпадает с этой строкой, вместо того чтобы искать пересечение классов.querySelectorAll часто приводит к «жесткому» падению 1С (ошибка обращения к памяти в mshtml.dll). Это связано с тем, что 1С не всегда корректно обрабатывает специфические типы данных (например, StaticNodeList), которые возвращает этот метод через COM-интерфейс.ng-dirty или ng-touched добавляются динамически. Если ваш код в 1С отрабатывает до завершения выполнения скриптов на странице, поиск по этим классам вернет пустоту.Чтобы избежать ошибок движка IE и падения платформы, проанализируем метод прямого перебора коллекции элементов. Этот способ работает медленнее, чем нативный поиск, но он гарантирует стабильность в 1С.
Вместо того чтобы полагаться на getElementsByClassName, мы получим все элементы нужного типа (например, все формы или все поля ввода) и проверим их классы вручную. Разберем по шагам реализацию этого метода:
// Получаем доступ к документу
ДокументHTML = ЭлементыФормы.ИЕ.Документ;
// Получаем коллекцию всех форм на странице
ВсеФормы = ДокументHTML.getElementsByTagName("form");
НужнаяФорма = Неопределено;
// Перебираем коллекцию (в COM-объектах индексы начинаются с 0)
Для Счетчик = 0 По ВсеФормы.length - 1 Цикл
ТекущаяФорма = ВсеФормы.item(Счетчик);
// Получаем строку классов элемента
СтрокаКлассов = ТекущаяФорма.className;
// Проверяем наличие ключевого класса в строке
Если Найти(СтрокаКлассов, "loginform__form-area") > 0 Тогда
НужнаяФорма = ТекущаяФорма;
Прервать;
КонецЕсли;
КонецЦикла;
// Если форма найдена, выполняем действие
Если НужнаяФорма <> Неопределено Тогда
НужнаяФорма.submit();
КонецЕсли;
Важный момент: При проверке через Найти() мы игнорируем порядок классов и наличие дополнительных динамических атрибутов Angular, что делает поиск очень гибким.
Если вы все же хотите использовать современные методы типа querySelector без падения 1С, необходимо заставить компоненту ActiveX работать в режиме IE11. Для этого проанализируем настройки реестра Windows.
Система проверяет ветку FEATURE_BROWSER_EMULATION, чтобы определить, какой движок использовать для конкретного исполняемого файла. Выполните следующие шаги:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION.1cv8.exe.11001 (в десятичной системе) или 0x2AF9 (в шестнадцатеричной).Это заставит 1С использовать актуальный движок рендеринга, что во многих случаях исправляет ошибки доступа к памяти при вызове querySelectorAll.
Рассмотрим ситуацию, когда классы слишком нестабильны. В этом случае мы можем использовать другие атрибуты элемента, такие как name, id, action или пользовательские атрибуты. Посмотрим на пример кода, который ищет форму по атрибуту autocomplete:
Функция НайтиФормуПоАтрибуту(Документ, ИмяАтрибута, ЗначениеАтрибута)
ВсеФормы = Документ.getElementsByTagName("form");
Для каждого Форма Из ВсеФормы Цикл
Если Форма.getAttribute(ИмяАтрибута) = ЗначениеАтрибута Тогда
Возврат Форма;
КонецЕсли;
КонецЦикла;
Возврат Неопределено;
КонецФункции
// Применение:
МояФорма = НайтиФормуПоАтрибуту(ЭлементыФормы.ИЕ.Документ, "autocomplete", "off");
Часто программисты 1С сталкиваются с тем, что вызов НужнаяФорма.submit() не приводит к отправке данных, особенно на сайтах с Angular. Это происходит потому, что фреймворк перехватывает событие отправки. Рассмотрим, как это обойти:
Попробуйте нажать на кнопку отправки программно: Вместо отправки самой формы, найдите кнопку (input или button) и вызовите метод click(). Это инициирует стандартную цепочку событий в браузере.
// Ищем кнопку внутри формы
Кнопки = НужнаяФорма.getElementsByTagName("button");
Для Счетчик = 0 По Кнопки.length - 1 Цикл
Кнопка = Кнопки.item(Счетчик);
// Например, ищем кнопку с определенным текстом или типом
Если Кнопка.type = "submit" Тогда
Кнопка.click();
Прервать;
КонецЕсли;
КонецЦикла;
Проанализируем еще одну причину неудач: попытка поиска элемента до того, как DOM-дерево было полностью построено. Всегда проверяйте состояние готовности документа перед запуском алгоритмов поиска. В 1С это удобно делать в обработчике события ДокументСформирован или через проверку свойства readyState.
Если ЭлементыФормы.ИЕ.Документ.readyState <> "complete" Тогда
// Документ еще загружается, поиск выполнять рано
Возврат;
КонецЕсли;
Подведем итог: Для максимально стабильной работы в 1С при взаимодействии с веб-страницами рекомендуется использовать метод перебора тегов (Solution 1), так как он наименее чувствителен к версии движка IE и не вызывает критических ошибок платформы. Использование реестра для переключения режима эмуляции — отличный вспомогательный инструмент, позволяющий использовать более современный синтаксис JavaScript.