Встала передо мной задача использовать в обработке HTML документ к которому подключена здоровенная библиотека на JavaScript. Задумался я об удобном размещении в обработке HTML разметки и скриптов а так же об удобном встраивании скриптов в документ перед его выполнением. В результате было найдено несколько достойных решений:
Размещение HTML документа и скриптов в макетах обработке
Было принято решение HTML разметку и скрипты хранить в макетах обработки. Для каждого документа HTML и для каждого скрипта или библиотеки скриптов свой макет. Ниже пример такой организации:
На скриншоте находится три макета.
HTML_DOC — макет в котором находится документ HTML. Тип макета HTML документ
script_01, script_02 — макеты в которых находятся скрипты на JavaScript. Тип макета Текстовый документ.
Устройство документа HTML для удобного подключения скриптов
Вначале покажу содержимое HTML документа моего примера
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="__STYLE__" rel="stylesheet" type="text/css">
<meta name="GENERATOR" content="MSHTML 11.00.9600.19003">
<base href="/redirect.php?url=djhjb25maWc6Ly9jMWQzZTdkMi03MTUwLTQ3ZmMtOGRjYy0xNThlMjBlNTE5OTUvbWRvYmplY3QvaWQ2MTI5YzI1Ni1iMWVjLTRlMTYtOTUxMi0xNDljNjhkMzdjYWUvOGViNGZhZDEtMWZhNi00MDNlLTk3MGYtMmMxMmRiYjQzZTIz">
<script src="script_01"></script>
<script src="script_02"></script>
</head>
<body>
<div>
<p>
<h1>TEST_JS</h1>
</p>
</div>
<div id="block1">
<p>Текст скрываемого блока 1</p>
</div>
<div id="block2">
<p>Текст скрываемого блока 2</p>
</div>
</body>
</html>
В секции <head> объявлено подключение двух скриптов с помощью конструкции <script src="script_ХХ"></script> Документ считает, что скрипты находятся в ресурсах "script_01" и "script_02". Количество подключаемых скриптов не ограничено, два взято для примера.
Я воспользовался следующими возможностями документа:
- подключать можно много скриптов, обрамляя каждый конструкцией <script></script>
- скрипт может находится на внешнем ресурсе и документ его самостоятельно импортирует при построении дерева
- платформа 1С предоставляет инструменты для манипулирования атрибутами документа, поэтому "фейковые" пути к скриптам, типа script_01 или script_02 я смогу подменить на истинные пути реальных файлов.
Перемещение скриптов в папку на локальном диске
Напомню, что скрипты у нас располагаются в текстовом макете обработки. Браузер 1С при исполнении HTML документа может импортировать скрипт с внешнего ресурса, в том числе из папки на локальном диске. Код копирования из макета на диск прост: Здесь свойство ОО это объект обработка.
сПутьКФайлу = ПолучитьИмяВременногоФайла("js");
макетJS = ОО.ПолучитьМакет(сИмяМакетаСкрипта);
макетJS.Записать(сПутьКФайлу);
Путь к файлу как URL
Мы скопировали файл скрипта на диск и он располагается, например по пути c: empscript_01.js Браузер 1С не сможет импортировать скрипт если путь к ресурсу указать как путь Windows. То есть, вот так работать не будет:
<script src="c: empscript_01.js"></script>
Проблема в пути, его нужно указывать как URL, добавляя префикс file:///. Вот так будет все в порядке:
<script src="file:///c:/temp/script_01.js"></script>
сделаем функцию преобразования локального пути в URL
&НаКлиентеНаСервереБезКонтекста
Функция ПутьКФайлуКакURL(сПуть)
Возврат "file:///"+СокрЛП(СтрЗаменить(сПуть,"","/"));
КонецФункции
Подмена в HTML документе "фейковых путей на локальные"
Последний шаг нашего плана изменить документ HTML и подставить настоящие пути к ресурсам вместо "фейковых". В начале получим коллекцию элементов <script>. Помните, в документе их может быть несколько?
элементыScript = документHTML.ПолучитьЭлементыПоИмени("script");
Если элементыScript.Количество() = 0 Тогда
бВыполненоБезОшибок = Ложь;
Возврат бВыполненоБезОшибок;
КонецЕсли;
Теперь для каждого элемента <script> нашего документа изменим значение атрибута "src" указав правильный путь к ресурсу. Я применил одну военную хитрость, назвал "фейковый" ресурс в исходном документе и макет скрипта одинаково и таким образом по названию макета я понимаю в какой элемент коллекции подставить правильный ресурс.
Для каждого элементScript Из элементыScript Цикл
Если элементScript.Источник = сИмяМакетаСкрипта Тогда
элементScript.УстановитьАтрибут("src", ПутьКФайлуКакURL(сПутьКФайлу));
бВыполненоБезОшибок = Истина;
Возврат бВыполненоБезОшибок;
КонецЕсли;
КонецЦикла;
Выгрузка HTML документа в текст разметки
И самый последний шаг. Выгрузим наш документ в текст и передадим этот текст в элемент формы с типом "Поле HTML документа". Тут просто
&НаКлиентеНаСервереБезКонтекста
Функция ТекстHTMLДокумента(Знач документHTML, сТекстДокументаHTML)
Перем бВыполненоБезОшибок, ЗаписьDOM, ЗаписьHTML;
ЗаписьDOM = Новый ЗаписьDOM();
ЗаписьHTML = Новый ЗаписьHTML();
ЗаписьHTML.УстановитьСтроку();
Попытка
ЗаписьDOM.Записать(документHTML, ЗаписьHTML);
сТекстДокументаHTML = ЗаписьHTML.Закрыть();
бВыполненоБезОшибок = Истина;
Исключение
сТекстДокументаHTML = "";
бВыполненоБезОшибок = Ложь;
КонецПопытки;
Возврат бВыполненоБезОшибок;
КонецФункции
Итог
Подведем итог. Изначально HTML документ и скрипты существовали как макеты обработки. Скрипты мы сохранили как файлы на локальном диске. В HTML документе изменили элементы <script>, указав в них реальные пути до скриптов. Документ выгрузили в текст и передали его браузеру 1С в элементе формы "Поле HTML документа". Ура, все работает.
Дополнение от 09.10.2024
Известно, что начиная с версии платформы 8.3.14 в качестве веб движка используется WebKit. Теперь для DOM не доступно свойство parentWindow, через которое мы раньше вызывали скрипт. Для новых версий платформы 1С Предприятие нужно использовать свойство defaultView. В новой версии обработки, текст метода, который вызывает скрипт переписан так:
Если Лев(Элементы.HTML_Fild.ИнформацияПрограммыПросмотра, 11) = "Mozilla/5.0" Тогда
Элементы.HTML_Fild.Документ.defaultView.display_div(сИДБлока);
Иначе
Элементы.HTML_Fild.Документ.parentWindow.display_div(сИДБлока);
КонецЕсли;
То есть, я пытаюсь определить, какой движок используется платформой и после этого выбираю свойство DOM parentWindow или defaultView.
Обработка протестирована на платформе версии 8.3.15
К статье приложена новая версия обработки от 09.10.2024
Так же этот проект можно найти на GitHub
Фейковые = фальшивые, ложные
(1)контекст данного слова предполагает именно слово «фейковый» фальшивый и ложный здесь неуместны.И да не забудьте прицепиться к слову «контекст».
Альтернативные варианты:
— сразу поместить код JavaScript в HTML;
— разместить код JavaScript в текстовых макетах, но вместо того, чтобы сохранять во временные файлы — поместить код скриптов через СтрЗаменить() в HTML;
(4) Искал решение, как избежать обоих предложенных вами вариантов. Результат поиска данная статья.
(6)
Просто интересно кого ты назвал обезьяной? Меня или ТС? Давно заметил, оскорбления — отличительная черта «патриотов».
(6)
Не вижу в этом ничего плохого. У нас много слов из других языков и все хорошо, никто не умер.
(6)
В удобный для использования. Если слово не будет удобным, оно умрет само, если будет удобным, сделает великий и могучий еще более богатым.
Так и не услышал, что делать, со словами «контекст», «скрипт», «браузер», дальше лень искать, легко найти десяток почти в каждой статье. Нужен сервис который будет искать пендоские слова и заменять их на наши исконные родимые. Вот тогда заживем. Я гарантирую это.
(7)
Для вашего развития будет полезно узнать, что даже слова «Идиот» или «Дурачок» являются нормальными медицинскими терминами, которые отражают факт сути. Собственно «Обезьяна» в контексте (лат.) моего сообщения относится к этому в полной мере. Одна обезьяна сказала, другая понесла, третья подхватила.
Сугубо женская черта: чуть что, сразу надо сделать вид что тебя оскорбляют.
Я понял ваше мнение, что общаться на русско-английском суржике это хорошо. С вами все ясно.
Мое мнение, что общаться на литературном русском это хорошо. Другое дело, что у малого количества людей есть для этого сила воли, особенно это зависит от окружения.
Я слово «браузер» не использую, т.к. есть куда более русское слово «обозреватель».
Контекст, во-первых, это латинское слово, а во вторых, это литературное слово.
Аналогично «Скрипт» = сценарий.
В ваших мыслях встречаются здравые. Это похвально.
(5) Не работает обработка.
У меня КаталогВременныхФайлов() возвращает путь на сервере и сохраненные там файлы не видятся в html, выдается ошибка что функция не обнаружена
(5) При работе на сервере не работает — пришлось доработать — сначала запрашивать ресурсы, получать на клиенте файлы и передавать созданные пути обратно на сервер в процедуру формирования HTML и подставлять их там
(10) Спасибо за уточнение. Это правда, я на сервере не тестировал.
Что-то в webkit не работают внешние скрипты, расположенные локально. Фокус с «file:///» не помогает, относительные пути тоже не работают.
(12) Добрый день. На какой версии платформы проверяли?
(13) 8.3.16.1030. 8.3.14 тоже не загружалось. Может конечно это у меня что-то с локальными настройками безопасности, не знаю куда копать. У меня в одном из решений всё построено на leaflet, который с ie довольно сильно тормозит. А не webkit вообще не работает.
(14) Если вопрос еще актуален, то пришлите пожалуйста текст итогового HTML документа.
Файл — Сохранить как — Файл с расширением html.