Как найти HTML-элемент с несколькими классами в поле документа 1С и избежать падения программы

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

Работа с Полем HTML-документа в 1С часто преподносит сюрпризы, особенно когда речь идет об автоматизации взаимодействия с современными веб-сайтами. Одной из типичных проблем является поиск элементов, имеющих несколько CSS-классов (например, динамические классы Angular ng-dirty ng-valid). Стандартные методы JavaScript, вызываемые через COM-объект 1С, могут вести себя непредсказуемо: либо не находить элементы, либо приводить к аварийному завершению работы (сворачиванию) платформы 1С. В этой статье мы подробно разберем, почему это происходит и как реализовать надежный поиск элементов.

Выясним причину: почему стандартные методы не работают

Для начала проанализируем ситуацию с движком отображения. Поле HTML-документа в 1С (особенно в обычных формах) использует компоненту ActiveX Internet Explorer. Даже если у вас в системе установлен IE11 или Microsoft Edge, встроенный в 1С контроллер по умолчанию часто запускается в режиме эмуляции IE7 или IE8.

Рассмотрим основные технические нюансы:

  1. Ограничения метода getElementsByClassName: В старых версиях движка (IE8 и ниже) этот метод либо вообще не реализован, либо не поддерживает поиск по строке, содержащей несколько классов, разделенных пробелом. Если вы передаете строку "class1 class2", браузер пытается найти элемент, у которого атрибут class в точности совпадает с этой строкой, вместо того чтобы искать пересечение классов.
  2. Падение querySelectorAll: Использование более современного метода querySelectorAll часто приводит к «жесткому» падению 1С (ошибка обращения к памяти в mshtml.dll). Это связано с тем, что 1С не всегда корректно обрабатывает специфические типы данных (например, StaticNodeList), которые возвращает этот метод через COM-интерфейс.
  3. Динамические классы Angular: Если сайт написан на Angular или подобных фреймворках, классы типа ng-dirty или ng-touched добавляются динамически. Если ваш код в 1С отрабатывает до завершения выполнения скриптов на странице, поиск по этим классам вернет пустоту.

Решение 1: Универсальный перебор элементов (самый надежный способ)

Чтобы избежать ошибок движка IE и падения платформы, проанализируем метод прямого перебора коллекции элементов. Этот способ работает медленнее, чем нативный поиск, но он гарантирует стабильность в 1С.

Вместо того чтобы полагаться на getElementsByClassName, мы получим все элементы нужного типа (например, все формы или все поля ввода) и проверим их классы вручную. Разберем по шагам реализацию этого метода:


// Получаем доступ к документу
ДокументHTML = ЭлементыФормы.ИЕ.Документ;

// Получаем коллекцию всех форм на странице
ВсеФормы = ДокументHTML.getElementsByTagName("form");

НужнаяФорма = Неопределено;

// Перебираем коллекцию (в COM-объектах индексы начинаются с 0)
Для Счетчик = 0 По ВсеФормы.length - 1 Цикл
    ТекущаяФорма = ВсеФормы.item(Счетчик);
    
    // Получаем строку классов элемента
    СтрокаКлассов = ТекущаяФорма.className;
    
    // Проверяем наличие ключевого класса в строке
    Если Найти(СтрокаКлассов, "loginform__form-area") > 0 Тогда
        НужнаяФорма = ТекущаяФорма;
        Прервать;
    КонецЕсли;
КонецЦикла;

// Если форма найдена, выполняем действие
Если НужнаяФорма <> Неопределено Тогда
    НужнаяФорма.submit();
КонецЕсли;

Важный момент: При проверке через Найти() мы игнорируем порядок классов и наличие дополнительных динамических атрибутов Angular, что делает поиск очень гибким.

Решение 2: Исправление режима эмуляции через реестр

Если вы все же хотите использовать современные методы типа querySelector без падения 1С, необходимо заставить компоненту ActiveX работать в режиме IE11. Для этого проанализируем настройки реестра Windows.

Система проверяет ветку FEATURE_BROWSER_EMULATION, чтобы определить, какой движок использовать для конкретного исполняемого файла. Выполните следующие шаги:

  1. Откройте редактор реестра (regedit).
  2. Перейдите в ветку HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION.
  3. Создайте параметр DWORD (32 бита) с именем 1cv8.exe.
  4. Установите значение 11001 (в десятичной системе) или 0x2AF9 (в шестнадцатеричной).

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

Решение 3: Поиск по альтернативным атрибутам

Рассмотрим ситуацию, когда классы слишком нестабильны. В этом случае мы можем использовать другие атрибуты элемента, такие как name, id, action или пользовательские атрибуты. Посмотрим на пример кода, который ищет форму по атрибуту autocomplete:


Функция НайтиФормуПоАтрибуту(Документ, ИмяАтрибута, ЗначениеАтрибута)
    ВсеФормы = Документ.getElementsByTagName("form");
    Для каждого Форма Из ВсеФормы Цикл
        Если Форма.getAttribute(ИмяАтрибута) = ЗначениеАтрибута Тогда
            Возврат Форма;
        КонецЕсли;
    КонецЦикла;
    Возврат Неопределено;
КонецФункции

// Применение:
МояФорма = НайтиФормуПоАтрибуту(ЭлементыФормы.ИЕ.Документ, "autocomplete", "off");

Проблема программной отправки формы (Submit)

Часто программисты 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.

← На главную