HTML5 в ПолеHTMLДокумента на Управляемой форме - fireEvent в действии

18.04.15

Разработка - Работа с интерфейсом

Эта статья посвящена тому, как из ПолеHTMLДокумента управляемой формы вызывать Javascript и осуществлять вызовы 1С из Javascript, когда в ПолеHTMLДокумента используется Internet Explorer 9.

Скачать исходный код

Наименование Файл Версия Размер
Example_1C_JS_Interchange.epf
.epf 8,70Kb
84
.epf 0.1 8,70Kb 84 Скачать

Суть проблемы:

В ранних версиях Internet Explorer (далее IE) вплоть до IE8 вызовы функций Javascript (далее JS) можно было осуществлять примерно так:

ПолеHTMLДокумента.document.parentWindow.MyFunc (...);

Начиная с версии IE9 такие вызовы, а также вызовы через eval () не работают, однако именно с этой версии начинается поддержка HTML5 и объекта Canvas, который предоставляет огромные возможности по рисованию, работе с картинками, аудио и видео и т.д. Также начиная с IE9 размер строки картинки в формате Base64 не ограничен (в IE8 - до 32К).

Однако, взаимодействие между Javascript'ом (далее JS) и 1С выглядит не так, как в старых версиях.

Решение:

Решением является использование JS-функции fireEvent.

Далее в статье рассматриваются вызовы 1С->JS и JS->1С для IE9 на примере функций вычисления суммы 2 чисел в 1С и JS. Cоответсвенно, функция JS вызывается из 1С, а 1С-функция - из JS.

Стоит сказать, что описываемая схема передачи параметров функций и их результатов - не единственное возможное решение, но достаточно универсальное.

В обработке к статье - полная версия примера.

Итак, начнем:

Сначала укажем, что наш HTML-код должен выполняться на движке IE9. Для этого в разделе <head> напишем строчку:

<head>
...
    <meta http-equiv="X-UA-Compatible" content="IE=9" />
...

</head>
Идем дальше. Поскольку JS-функция fireEvent может получать в качестве параметра только данные, относящиеся к сообщению, организуем передачу данных через невидимые на странице HTML-контейнеры <DIV>.

    <div id="ExtCommand" style="display:none">extcommand</div>
    <div id="EventName" style="display:none">js_event</div>
    <div id="BufferData" style="display:none">js_result</div>

Можно обойтись и одним <DIV>, в нашем примере их несколько для наглядности. Содержимое DIV-контейнера (точнее, свойство innerHTML) имеет строковый тип.

ExtCommand - сюда будем передавать код вызываемой JS-функции.
EventName - здесь будет имя действия, которое нужно выполнить в 1С
BufferData - для передачи параметров или любых других строковых данных

Также нам понадобится невидимая кнопка для вызова JS-функций:

    <input type=button style="display:none" id="SendEvent" = "ExecCommand ()" />

И JS-функция ExecCommand (), которая будет выполнять любой JS-код, передаваемый из 1С.

    function ExecCommand ()
    {
        code = document.getElementById ("ExtCommand").innerHTML;
        result = "" + eval (code);
        document.getElementById ("BufferData").innerHTML = result;
    }

Вызов Javascript из 1С:

&НаКлиенте
Процедура КомандаJS(Команда)
    // формуруем текст команды JS
    лКомандаJS = СкриптПоШаблону("SumJS (%1, %2)", ФрмЧ (Число1), ФрмЧ (Число2));    
    // записываем команду JS в контейнер div
    Элементы.НТМЛ.Документ.getElementById ("ExtCommand").innerHTML = лКомандаJS;
    // Посылаем сообщение невидимой кнопке, чтобы выполнить команду JS
    лКоманда = Элементы.НТМЛ.Документ.getElementById ("SendEvent");    
    лРезЕ = лКоманда.fireEvent ("onclick");
    // получаем результат из контейнера DIV
    лРез = Элементы.НТМЛ.Документ.getElementById ("BufferData").innerHTML;
    Сумма = Число (лРез);
КонецПроцедуры

Вызов 1С из Javascript:

Разместим на HTML-странице такие элементы:

<body>
...
    Число 1:<input type=text id="Val1" value="4" /><br />
    Число 2:<input type=text id="Val2" value="5" /><br />
    Сумма  :<input type=text id="Summa" value="0" /><br />
    <input type=button id="Button1" value="Сумма" ()" /><br />
...
</body>

Их назначение понятно из названий.

Далее функция ExtSum, которая вызывает обработчик ПриНажатии у ПолеHTMLДокумента в 1С:

    function ExtSum ()
    {
        // параметры вызова - имя действия
        document.getElementById ("EventName").innerHTML = 'CalcSum';
        // параметры действия строкой через точку с запятой
        document.getElementById ("BufferData").innerHTML = Val1.value+";"+Val2.value;
        
        var evt = document.createEventObject();
        // вызывает обработчик "НТМЛПриНажатии" в 1С
        document.body.fireEvent('onclick', evt);
        document.getElementById ("Summa").value = document.getElementById ("BufferData").innerHTML;
    }

Ну, и обработчик ПриНажатии в 1С:

&НаКлиенте
Процедура НТМЛПриНажатии(Элемент, ДанныеСобытия, СтандартнаяОбработка)
    // получаем имя нашего события из контейнера DIV
    лИмяСобытия = Элементы.НТМЛ.Документ.getElementById ("EventName").innerHTML;
    // очищаем содержимое контейнера DIV
    Элементы.НТМЛ.Документ.getElementById ("EventName").innerHTML = "";
    Если лИмяСобытия = "CalcSum" Тогда
        // получаем параметры из контейнера DIV в виде строки через точку с запятой
        лПараметры = Элементы.НТМЛ.Документ.getElementById ("BufferData").innerHTML;
        лПараметры = СтрЗаменить(лПараметры, ";", Символы.ПС);
        лЧисло1 = Число (СтрПолучитьСтроку(лПараметры, 1));
        лЧисло2 = Число (СтрПолучитьСтроку(лПараметры, 2));
        лСумма = лЧисло1+лЧисло2;
        лРез = ФрмЧ(лСумма);
        // помещаем результат в DIV
        Элементы.НТМЛ.Документ.getElementById ("BufferData").innerHTML = лРез;
        // здесь происходит возврат в JS
    Иначе
    // обработка других событий 
    КонецЕсли;
КонецПроцедуры

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

 

 

html javascript ПолеHTMLДокумента

См. также

Управление дашбордами

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Платные (руб)

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

2400 руб.

29.06.2020    17208    23    4    

37

Новогоднее оформление для 1С

Работа с интерфейсом Платформа 1С v8.3 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Зарплата и Управление Персоналом 3.x 1С:Управление нашей фирмой 3.0 Бесплатно (free)

Добавьте новогоднего настроения! Расширение создает декорацию в виде гирлянды на некоторых формах объектов.

27.12.2023    11699    776    elcoan    47    

108

Конструктор HTML, CSS и javascript

Инструментарий разработчика Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Подходит для создания web-страниц для замены управляемых форм 1С, красивых отчетов, интерфейса мобильного приложения на платформе 1С и для простых страниц веб-сайтов.

2 стартмани

10.04.2023    10222    157    acces969    31    

120

Модель состояния для MVC

Работа с интерфейсом Программист Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

"MVC плохо применима в 1С" - познакомьтесь с моделью состояния и, возможно, ваше мнение поменяется! Представленное решение является эволюционным развитием идеи реализации MVC для 1С. В новой версии добавлены DSL для описания модели состояния, а также параметризация свойств параметров и элементов формы.

1 стартмани

05.07.2022    4217    kalyaka    4    

31

Познавательный PowerShell

Языки и среды Системный администратор Программист Бесплатно (free)

Еще немного PowerShell нам в помощь.

13.05.2022    6783    Infostart    18    

114

Условное оформление элементов форм в пользовательском режиме 1С (управление видимостью и доступностью элементов форм)

Работа с интерфейсом Платформа 1С v8.3 Платные (руб)

Подсистема условного оформления элементов форм (далее подсистема) предназначена для настройки оформления элементов форм (видимость, доступность, цвет фона, цвет текста и прочее) в пользовательском режиме 1С. Также подсистему возможно использовать для ограничения доступа к реквизитам формы для определенных пользователей (или групп пользователей).

6000 руб.

18.01.2022    9114    1    2    

6
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Patriot1S 99 18.04.15 21:10 Сейчас в теме
А в Linux будет работать?
2. GusevNA 360 18.04.15 22:01 Сейчас в теме
(1) Patriot1S, Здесь все сделано стандартными средствами 1С и стандартными средствами HTML-JS. Насчет Linux - все зависит от того, как там реализован элемент управляемой формы ПолеHTMLДокумента.
Если аналогично Win, тогда нужно проверить платформу на баги (в релизе 8.3.5.1383 в тонком клиенте под Windows 7 просто баг выдавался и через Попытка-Исключение не обрабатывался).

Так что если кто-нибудь попробует под Linux, буду очень благодарен за комменты.

3. vandalsvq 1558 19.04.15 01:12 Сейчас в теме
(0) Обрати внимание, в ие 9+ createEventObject не поддерживается. Точнее в 9 он остался для обратной совместимости, а в 10 и 11 выпилили. Поэтому я бы советовал использовать следующий код

if (document.createEvent) {
    var evt = document.createEvent('MouseEvents');
    evt.initEvent('click', true, false);
    document.body.dispatchEvent(evt);
} else if(document.createEventObject) {
    document.body.fireEvent('onclick');
}


И кстати можно еще объявить переменные в корне вроде

var eventName	 = '';
var eventParam = [];


Ну а потом обращаться к ним через ДокументHTML.parentWindow.EventName (или EventParam)
magv; BigB; +2 Ответить
4. GusevNA 360 19.04.15 15:06 Сейчас в теме
(3) vandalsvq, Большое спасибо за код для IE10 - обязательно потестирую, когда время появится.

По этому примеру - он родился из реальной задачи, и там нужна была функциональность IE, которая начинается с версии 9.
Чтобы не тестировать HTML-JS для других версий IE, 9-я версия фиксирется строкой:

<meta http-equiv="X-UA-Compatible" content="IE=9" />

Она обозначает, что страница находится в режиме совместимости именно с IE9, даже если установлен IE10 или IE11.

А вот вызовы типа
ДокументHTML.parentWindow.EventName
начиная с IE9 не работают - для этого и используется fireEvent

Чтобы такие вызовы заработали, можно попробовать раздел реестра:
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_USE_LEGACY_JSCRIPT

Более подробно про режимы совместимости можно почитать здесь:
https://msdn.microsoft.com/ru-ru/library/cc288325%28v=vs.85%29.aspx
и здесь:
http://xiper.net/manuals/html/meta-tags/http-equiv/x-UA-Compatible

Про FEATURE_USE_LEGACY_JSCRIPT здесь:
http://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version
6. vandalsvq 1558 19.04.15 19:02 Сейчас в теме
(4) не соглашусь на счёт параметров. Тестил режимы совместимости 9,10,11. В системе стоит ie11, win7 sp2. Все работало.
Линух пока не тестил.
15. GusevNA 360 21.04.15 04:22 Сейчас в теме
(3) vandalsvq, Если указать IE10
<met a http-equiv="X-UA-Compatible" content="IE=10" />

выдается ошибка "Произошла исключительная ситуация..." и для fireEvent и для click (). Ошибка не отлавливается Попыткой-Исключением. Точнее сказать, JS-функция отрабатывает, а потом выдается ошибка.
Похоже, это баг платформы, аналогичный тому, который был в 8.3.5.1383, только теперь уже под IE10.

Так что полноценного тестирования под движок IE10 не получается.
5. sikuda 676 19.04.15 18:47 Сейчас в теме
В Linux
не работает никакой fireEvent не работает
Элементы.НТМЛ.Документ.getElementById ("BufferData").innerHTML - работает!!! 8.3.6.1920
7. vandalsvq 1558 19.04.15 19:03 Сейчас в теме
(5) sikuda, А мой пример с createEvent работает?
8. sikuda 676 19.04.15 20:44 Сейчас в теме
(7) vandalsvq, Да я честно не осознал зачем вообще fireEvent
Элементы.НТМЛ.Документ.getElementById ("SendEvent").click() - работает и в Windows и в Linux.

И в функции ExecCommand () добавь строку alert(navigator.userAgent); Ты будешь сильно удивлен своим IE9.
BigB; Yashazz; EliasShy; ZOMI; +4 Ответить
9. Поручик 4679 20.04.15 07:15 Сейчас в теме
navigator.userAgent покажет IE 7, какой бы режим совместимости не устанавливать.
ZOMI; sikuda; +2 Ответить
10. yukon 148 20.04.15 11:14 Сейчас в теме
(9) Поручик,
navigator.userAgent покажет IE 7, какой бы режим совместимости не устанавливать.

Это смотря где устанавливать. Если здесь: https://msdn.microsoft.com/en-us/library/ie/ee330730(v=vs.85).aspx#browser_emulation , то может и взетит.
11. GusevNA 360 20.04.15 18:43 Сейчас в теме
Еще раз по поводу вызовов типа ПолеHTMLДокумента.document.parentWindow.MyFunc1 ()

<!DO CTYPE html>
<ht ml>
<head>
<title>1C JS Interchange</title>
<met a http-equiv="Content-Type" content="text/html; charset=utf-8" />
<met a http-equiv="X-UA-Compatible" content="IE=8" />
<sc ript>
var var1 = "Debug_var";
function Debug1 ()
{
alert ("Debug");
}
</sc ript>
</head>
<body>
<p>Body</p>
</body>
</html>

Вызовы работают:
Рез = Элементы.НТМЛ.Документ.parentWindow.var1;
Сообщить (Рез); // выводит Debug_var
Элементы.НТМЛ.Документ.parentWindow.Debug1 (); // выводит MsgBox "Debug"

Если написать
<met a http-equiv="X-UA-Compatible" content="IE=9" />
При настройках IE по умолчанию ВЫЗОВЫ НЕ РАБОТАЮТ

Если вызовы все-таки работают, значит, накручены настройки IE в самом IE или в реестре.

Если Вы пишете под конкретного заказчика, и Вам доступны и настройки IE, и реестр, то можно все настроить так, как нужно.
Если Вы пишете обработки для всех, то лучше исходить из того, что настройки стоят по умолчанию.
12. GusevNA 360 20.04.15 19:33 Сейчас в теме
Насчет fireEvent и Click

Click также отлавливается элементом ПолеHTMLДокумента в событии ПриНажатии, так что можно использовать и такой метод. (тестировалось на Win7 32 bit 1С 8.3.5.1517). Судя по комментам, должно работать и в Linux.

Но, как я понял замысел разработчиков IE, click () - это непосредственное нажатие кнопки мыши, а fireEvent - это именно программный вызов события, так что с точки зрения правильности кода все-таки стоит использовать fireEvent

И еще насчет ПолеHTMLДокумента в Windows и Linux.
ПолеHTMLДокумента, насколько я знаю, использует ActiveX-компонент Webbrowser, а он работает на движке IE.
По крайней мере, так было в обычных формах. В УФ, возможно, также, только надстройка над компонентом Webbrowser изменена.
А в Linux на коком браузерном движке работает ПолеHTMLДокумента? Может, кто знает, напишите, плиз.
13. sikuda 676 20.04.15 23:06 Сейчас в теме
(12) В Linux старенький web-kit:
Mozilla/5.0 (X11; Linux i686) AppleWebKit/538.15 (KHTML, like Gecko) Version/8.0 Safari/538.15

Насчет fireEvent не буду переубеждать.
14. GusevNA 360 21.04.15 04:12 Сейчас в теме
(13) sikuda, Спасибо, буду иметь ввиду. Попозже буду тестить под Linux на Virtualbox и отпишусь по результатам.

Кстати сказать, если вызовы fireEvent в 1С и JS заменить на вызов click (), то все работает также. Наверно, под Linux так и нужно делать.
16. MarSeN 984 21.04.15 18:51 Сейчас в теме
17. Feelthis 38 22.04.15 11:39 Сейчас в теме
Может есть у кого примеры (хотя бы текстом, лучше картинки может и т. д.) реализаций крутых возможностей Javascript + 1C? Для чего полезного вы используете JavaScript?
У себя мы реализовывали только работу с картой google и yandex и построение маршрутов в 1С.
18. Yashazz 4744 22.04.15 13:35 Сейчас в теме
Поправьте, если ошибаюсь, но то чудо, которое засунуто в 1С под видом ПолеHTML, ведь никак не выше версии IE 8, так?
20. GusevNA 360 23.04.15 02:00 Сейчас в теме
(18) Yashazz, Сейчас уже точно поддерживает движок IE 9 в релизе 8.3.5.1517. Все описанные фичи HTML5 для IE9 есть, так что налицо движение вперед:-))
19. vandalsvq 1558 22.04.15 15:10 Сейчас в теме
(0) хочу сказать что в своем сообщении (3) я был немного введен в заблуждение поведением платформы 1С.
8.3.5- получение параметров через точку невозможно, 8.3.6.1960 - работает.

И метод CreateEvent работает как то странно. Покопавшись, соглашусь с ранее высказанной мыслью что click() - самый универсальный способ (тем более как говорит sikuda он еще и кроссплатформенный).

Что же касается передачи параметров, то мое мнение можно через атрибуты их передавать.

HTML
<div id='name' data-eventName='' data-eventParam='' ...></div>


JS
getElementById('name').setAttribute('data-eventName', 'ИмяПроцедуры1С');
getElementById('name').getAttribute('data-eventName');


имена могут быть любые, но я делаю с префиксом data, надеясь что когда нибудь дата-атрибуты будут поддерживаться правильно (через dataSet).
BigB; sikuda; +2 Ответить
21. sikuda 676 27.04.15 15:56 Сейчас в теме
(19) vandalsvq, Да причем с точки зрения браузера не обязательно в HTML их прописывать.

<div id='name'></div>
getElementById('name').getAttribute('data-eventName'); -> NULL
getElementById('name').setAttribute('data-eventName', 'Значение');

Работает! и в 8.1
BigB; GusevNA; +2 Ответить
22. GusevNA 360 21.05.15 19:09 Сейчас в теме
После установки релиза 1С 8.3.1570 пример заработал для IE10:
<meta http-equiv="X-UA-Compatible" content="IE=10" />

И странный эффект - перестала выдаваться ошибка в релизе 8.3.1517
Проверялось на Windows 8 32 bit
23. SmokeAce 09.03.16 21:40 Сейчас в теме
Спасибо автору и всем кто участвовал в обсуждении, помогло в боевых условиях.
24. Dilovar9 64 04.05.16 07:40 Сейчас в теме
А как быть если innerHTML перестал работать в IE 11 ???
25. GusevNA 360 04.05.16 12:36 Сейчас в теме
(24) Dilovar9, Можно попробовать разные варианты строки:
<meta http-equiv="X-UA-Compatible" content="IE=8" />
Весь HTML должен работать как в IE8
Если не поможет, то поковырять настройки Винды, ИЕ, возможно, антивирусов.


26. Businka76 72 25.06.16 00:12 Сейчас в теме
обработка не помогла. обсуждение навело на результат. помог только ключ в реестре.
FEATURE_BROWSER_EMULATION позволяет выставить любой браузер.
10000 (0x2710) IE10
9000 (0x2328) IE9
8000 (0x1F40) IE8
7000 (0x1B58) IE7

более полно о доступных значениях ключей и что с ними делать есть здесь
https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx
27. GusevNA 360 25.06.16 10:05 Сейчас в теме
(26) Businka76, бывает, что не работает из-за настроек Windows (IE все-таки компонент Windows) или из-за антивирусов
28. fixin 4258 06.06.22 20:55 Сейчас в теме
CreateEventObject - это для IE

Вот пример для нормальных, современных браузеров (нагуглил, применил):

        var evt = document.createEvent('MouseEvents');
        evt.initEvent('click', true, false );
        evt.data = "My Data";
        document.dispatchEvent(evt);
Оставьте свое сообщение