Мухи отдельно, котлеты отдельно. Еще раз про HTML и JavaScript

Это еще одна статья про документ HTML и JavaScript. Уклон сделан на организацию хранения HTML документа и скриптов а так же на подключение скриптов к документу.

Встала передо мной задача использовать в обработке 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

13 Comments

  1. Steelvan

    Фейковые = фальшивые, ложные

    Reply
  2. webester

    (1)контекст данного слова предполагает именно слово «фейковый» фальшивый и ложный здесь неуместны.И да не забудьте прицепиться к слову «контекст».

    Reply
  3. PerlAmutor

    Альтернативные варианты:

    — сразу поместить код JavaScript в HTML;

    — разместить код JavaScript в текстовых макетах, но вместо того, чтобы сохранять во временные файлы — поместить код скриптов через СтрЗаменить() в HTML;

    Reply
  4. infosoft-v

    (4) Искал решение, как избежать обоих предложенных вами вариантов. Результат поиска данная статья.

    Reply
  5. webester

    (6)

    Завтра следующая обезьяна

    Просто интересно кого ты назвал обезьяной? Меня или ТС? Давно заметил, оскорбления — отличительная черта «патриотов».

    (6)

    и вы будете говорить что именно оно подходит для выражения мысли

    Не вижу в этом ничего плохого. У нас много слов из других языков и все хорошо, никто не умер.

    (6)

    русский великий и могучий такие как вы превращают в русско-английский суржик, никакого у вас нет самоуважения

    В удобный для использования. Если слово не будет удобным, оно умрет само, если будет удобным, сделает великий и могучий еще более богатым.

    Так и не услышал, что делать, со словами «контекст», «скрипт», «браузер», дальше лень искать, легко найти десяток почти в каждой статье. Нужен сервис который будет искать пендоские слова и заменять их на наши исконные родимые. Вот тогда заживем. Я гарантирую это.

    Reply
  6. Steelvan

    (7)

    Для вашего развития будет полезно узнать, что даже слова «Идиот» или «Дурачок» являются нормальными медицинскими терминами, которые отражают факт сути. Собственно «Обезьяна» в контексте (лат.) моего сообщения относится к этому в полной мере. Одна обезьяна сказала, другая понесла, третья подхватила.

    Давно заметил, оскорбления — отличительная черта «патриотов».

    Сугубо женская черта: чуть что, сразу надо сделать вид что тебя оскорбляют.

    Не вижу в этом ничего плохого. У нас много слов из других языков и все хорошо, никто не умер.

    Я понял ваше мнение, что общаться на русско-английском суржике это хорошо. С вами все ясно.

    Мое мнение, что общаться на литературном русском это хорошо. Другое дело, что у малого количества людей есть для этого сила воли, особенно это зависит от окружения.

    Я слово «браузер» не использую, т.к. есть куда более русское слово «обозреватель».

    Контекст, во-первых, это латинское слово, а во вторых, это литературное слово.

    Аналогично «Скрипт» = сценарий.

    Нужен сервис который будет искать пендоские слова и заменять их на наши исконные родимые.

    В ваших мыслях встречаются здравые. Это похвально.

    Reply
  7. s_vidyakin

    (5) Не работает обработка.

    У меня КаталогВременныхФайлов() возвращает путь на сервере и сохраненные там файлы не видятся в html, выдается ошибка что функция не обнаружена

    Reply
  8. s_vidyakin

    (5) При работе на сервере не работает — пришлось доработать — сначала запрашивать ресурсы, получать на клиенте файлы и передавать созданные пути обратно на сервер в процедуру формирования HTML и подставлять их там

    Reply
  9. infosoft-v

    (10) Спасибо за уточнение. Это правда, я на сервере не тестировал.

    Reply
  10. GSA3D

    Что-то в webkit не работают внешние скрипты, расположенные локально. Фокус с «file:///» не помогает, относительные пути тоже не работают.

    Reply
  11. infosoft-v

    (12) Добрый день. На какой версии платформы проверяли?

    Reply
  12. GSA3D

    (13) 8.3.16.1030. 8.3.14 тоже не загружалось. Может конечно это у меня что-то с локальными настройками безопасности, не знаю куда копать. У меня в одном из решений всё построено на leaflet, который с ie довольно сильно тормозит. А не webkit вообще не работает.

    Reply
  13. infosoft-v

    (14) Если вопрос еще актуален, то пришлите пожалуйста текст итогового HTML документа.

    Файл — Сохранить как — Файл с расширением html.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *