Как исправить ошибку «Значение не является значением объектного типа (Closed)» при работе с HTML-полем в 1С

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

При обновлении платформы 1С:Предприятие до версий 8.3.14, 8.3.18 и выше многие разработчики сталкиваются с тем, что привычный код для взаимодействия с Полем HTML-документа перестает работать. Чаще всего это проявляется в виде ошибки «Значение не является значением объектного типа (Closed)» или аналогичной ошибки для метода (Eval). В этой статье мы подробно разберем, почему это происходит и как адаптировать ваш код под новые реалии платформы.

Почему старый код перестал работать?

Разберем первопричину. В старых версиях платформы 1С для отображения HTML-контента использовался движок Internet Explorer (Trident). Взаимодействие с ним строилось через COM-объекты, где свойство parentWindow было стандартным способом доступа к глобальному объекту окна из объекта документа. Однако в современных версиях платформы произошел переход на движки WebKit и Chromium (в зависимости от режима работы), а также изменились механизмы маршалинга данных между 1С и браузерным компонентом.

Проанализируем ситуацию: когда вы обращаетесь к Элементы.ОписаниеHTML.Документ.parentWindow, новая платформа возвращает Неопределено, так как свойство parentWindow является специфичным для Microsoft и более не поддерживается. Соответственно, любая попытка проверить свойство .Closed или вызвать метод .Eval() у значения Неопределено приводит к аварийному завершению процедуры.

Переход с parentWindow на defaultView

Первое и самое важное изменение, которое нам необходимо внести в код — это замена обращения к окну. В соответствии с современными стандартами DOM (Document Object Model), для получения доступа к объекту окна через документ следует использовать свойство defaultView.

Рассмотрим пример исправления условия проверки состояния окна. Вместо старого варианта:


// Устаревший способ
Если Не Элементы.ОписаниеHTML.Документ.parentWindow.Closed Тогда
    // Ваш код
КонецЕсли;

Мы должны использовать следующий синтаксис:


// Современный способ
Если Элементы.ОписаниеHTML.Документ.defaultView <> Неопределено 
   И Не Элементы.ОписаниеHTML.Документ.defaultView.Closed Тогда
    // Ваш код
КонецЕсли;

Обратите внимание, что мы добавили проверку на Неопределено. Это критически важно для обеспечения стабильности работы формы, так как в момент инициализации документа объект defaultView может быть еще не доступен.

Проблема метода Eval и регистра символов

Второй важный аспект касается выполнения произвольного JavaScript-кода. В среде Internet Explorer метод часто назывался Eval (с заглавной буквы). Однако в стандартном JavaScript метод пишется как eval (строчными буквами). Новая платформа 1С стала крайне чувствительна к регистру имен методов при обращении к объектам HTML-документа.

Выясним причину ошибки в Сообщении 5 из обсуждения. Код Body.Документ.parentWindow.Eval(...) падал, потому что parentWindow не существует, а Eval не является методом объекта. Исправленный вариант должен использовать defaultView.eval или, что еще лучше, прямой вызов необходимых функций редактора.

Работа с визуальными редакторами (TinyMCE и CKEditor)

Если вы используете встроенные редакторы типа TinyMCE или CKEditor, то современная платформа позволяет обращаться к их программному интерфейсу (API) напрямую через объект окна, минуя медленный метод eval. Рассмотрим, как это реализовать на практике.

Для редактора TinyMCE:

Вместо того чтобы передавать строку кода в функцию интерпретации, мы можем обратиться к активному редактору напрямую:


// Получение контента из TinyMCE
Попытка
    Окно = Элементы.ОписаниеHTML.Документ.defaultView;
    ТекстСообщения = Окно.tinyMCE.activeEditor.getContent();
Исключение
    ТекстСообщения = "";
    Сообщить("Ошибка получения данных из редактора: " + ОписаниеОшибки());
КонецПопытки;

Для редактора CKEditor:

Аналогично поступим и с CKEditor. Проанализируем пример записи данных в редактор, который был предложен в Сообщении 4 форума. Здесь важно правильно передать параметры в функцию setData.


// Установка контента в CKEditor
Процедура УстановитьТекстВРедактор(ЭлементФормыHTML, ИсходныйТекст)
    Документ = ЭлементФормыHTML.Документ;
    Окно = Документ.defaultView;
    
    // Очищаем текст от символов переноса строк, чтобы не сломать JS-строку
    ОчищенныйТекст = СтрЗаменить(ИсходныйТекст, Символы.ПС, " ");
    
    // Прямой вызов метода API редактора
    Окно.CKEDITOR.instances.editor1.setData(ОчищенныйТекст);
КонецПроцедуры

Подготовка данных для передачи в JavaScript

Одной из часто встречающихся проблем является передача многострочного текста из 1С в JavaScript-функцию. Если в переменной html содержатся символы переноса строки (Символы.ПС), то при попытке выполнить код JavaScript возникнет синтаксическая ошибка, так как строковая константа в JS не может просто так разрываться на несколько строк.

Разберем, как правильно подготовить строку:

  1. Используйте функцию СтрЗаменить(Текст, Символы.ПС, " ") для удаления переносов.
  2. Если переносы важны, заменяйте их на HTML-тег <br> или на экранированный символ \n.
  3. Следите за кавычками. Если ваш HTML-текст содержит одинарные кавычки, а вы обрамляете строку в JS тоже одинарными кавычками, это приведет к ошибке. Используйте экранирование или замену кавычек.

Итоговый алгоритм исправления кода

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

  1. Проведите глобальный поиск по конфигурации или обработке слова parentWindow и замените его на defaultView.
  2. Проверьте регистр: убедитесь, что при вызове методов JavaScript вы используете правильный регистр (например, eval вместо Eval, getContent вместо GetContent).
  3. Добавьте проверки: перед обращением к объектам внутри HTML-документа всегда проверяйте наличие самого документа и его defaultView.
  4. Оптимизируйте вызовы: по возможности откажитесь от использования eval в пользу прямого обращения к методам JS-объектов через точку. Это не только надежнее, но и упрощает отладку кода.

Соблюдение этих правил позволит вашим решениям стабильно работать на любой современной версии платформы 1С:Предприятие 8.3, независимо от используемого движка отображения контента.

← На главную