Как избавиться от «прыжков» управляемой формы при динамическом обновлении времени или данных?

Программист 1С v8.3 (Управляемые формы)
← На главную

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

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

Почему форма «прыгает»? Выясняем причину

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

Если форма имеет сложную структуру, содержит группы с автоматическим распределением высоты или элементы, у которых установлено свойство «Растягивать по вертикали», система может «потерять» текущую позицию прокрутки. В результате фокус или видимая область принудительно возвращаются к активному элементу или в начало формы. Ситуация усугубляется, если обновление данных провоцирует неявный серверный вызов, что заставляет форму полностью обновить свое состояние.

Способ 1. Использование Поля ввода вместо Декорации

Как показывает практика и обсуждение в теме, использование элемента вида Декорация — Надпись для часто обновляемых данных — не самое удачное решение. Вместо этого рассмотрим использование обычного Поля ввода, связанного с реквизитом формы типа Строка или Дата.

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

  1. Установим свойство Вид в значение Поле ввода.
  2. Установим свойство Только просмотр в значение Истина. Это позволит тексту оставаться черным (в отличие от свойства Доступность = Ложь, которое делает текст серым).
  3. Установим свойство Рамка в значение Нет.
  4. В свойстве Цвет фона выберем Цвет фона формы или оставим Авто.
  5. Установим флаг Пропускать при вводе в значение Истина, чтобы пользователь не попадал в это поле при нажатии клавиши Tab.

Разберем пример кода для обновления такого поля:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    // Подключаем обработчик с интервалом в 1 секунду
    ПодключитьОбработчикОжидания("ОбновитьОтображениеВремени", 1, Ложь);
КонецПроцедуры

&НаКлиенте
Процедура ОбновитьОтображениеВремени() Экспорт
    // Прямое присваивание значения реквизиту формы, связанному с полем ввода
    ТекущееВремяНаФорме = Формат(ТекущаяДата(), "ДЛФ=Т");
КонецПроцедуры

Важный момент: при таком подходе изменение значения реквизита формы обычно не вызывает полного пересчета интерфейса, и форма перестает «дергаться».

Способ 2. Использование Поля HTML-документа (Профессиональный метод)

Если первый способ не помогает (например, из-за специфической верстки формы), воспользуемся самым надежным методом — интеграцией HTML. Суть метода заключается в том, что мы создаем на форме поле HTML-документа, которое работает внутри своего изолированного контейнера. Изменения внутри этого контейнера никак не влияют на геометрию основной управляемой формы 1С.

Рассмотрим по шагам, как это реализовать:

1. Создадим на форме реквизит с типом Строка (например, СодержимоеHTML) и вытащим его на форму как Поле HTML-документа.

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

Проанализируем пример формирования такого HTML-текста:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    СодержимоеHTML = 
    "<html>
    |<body style='margin:0; padding:0; overflow:hidden; background-color: transparent;'>
    |   <div id='clock' style='font-family: Arial; font-size: 14px; color: #333;'></div>
    |   <script>
    |       function updateClock() {
    |           var now = new Date();
    |           var time = now.getHours() + ':' + 
    |                      ('0' + now.getMinutes()).slice(-2) + ':' + 
    |                      ('0' + now.getSeconds()).slice(-2);
    |           document.getElementById('clock').innerHTML = time;
    |       }
    |       setInterval(updateClock, 1000);
    |       updateClock();
    |   </script>
    |</body>
    |</html>";
КонецПроцедуры

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

Способ 3. Оптимизация структуры групп и свойств растягивания

Если вы все же хотите использовать стандартные средства 1С, проанализируем настройки размещения элементов. Часто «прыжки» связаны с тем, что система не может зафиксировать высоту элементов.

Попробуем следующие шаги:

Критический разбор: Почему нельзя использовать Фоновые задания для часов?

В некоторых сообщениях на форумах встречается совет запускать обновление времени через Фоновое задание. Разберем, почему это плохая идея. Каждое фоновое задание — это отдельный сеанс на сервере 1С. Запуск нового сеанса каждую секунду создаст колоссальную нагрузку на кластер серверов и сетевой трафик. Это приведет не к решению проблемы скролла, а к тотальному зависанию интерфейса у всех пользователей информационной базы. Фоновые задания предназначены для длительных расчетов, а не для обновления интерфейсных мелочей.

Подведем итоги

Для решения проблемы «прыгающей» формы мы рекомендуем придерживаться следующего алгоритма:

  1. Вариант минимум: Замените декорацию на Поле ввода с включенным флагом Только просмотр и отключенной рамкой. Это решает проблему в 90% случаев.
  2. Вариант максимум (рекомендуемый): Используйте Поле HTML-документа с локальным JavaScript кодом. Это самый технологичный способ, который экономит ресурсы сервера и гарантирует стабильность интерфейса.
  3. Дополнительно: Старайтесь избегать изменения свойств Заголовок у элементов формы в обработчиках ожидания, так как это наиболее частая причина принудительной перерисовки всей формы. Если нужно менять текст, меняйте значение Данных (реквизита), связанных с элементом.

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

← На главную