Как реализовать автоматическую прокрутку поля HTML-документа до конца в 1С 8.3

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

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

Анализ причины проблемы: переход на движок Chromium

Начиная с версии платформы 8.3.14, компания 1С перешла с использования движка Internet Explorer (MSHTML) на Chromium (CEF — Chromium Embedded Framework) для рендеринга HTML-контента в управляемых формах. Это привело к изменению поведения объектной модели документа (DOM). Основные причины, по которым старые скрипты перестали работать, заключаются в следующем:

  1. Асинхронность рендеринга: В новом движке событие onload может срабатывать до того, как платформа полностью рассчитает геометрические размеры элементов (высоту блоков). В этот момент scrollHeight возвращает 0, и прокрутка не происходит.
  2. Изменение основного элемента прокрутки: В современных стандартах за прокрутку всей страницы часто отвечает не document.body, а document.documentElement (тег html).
  3. Цикл событий 1С: При программной установке текста в поле HTML 1С требуется время на передачу данных в браузерный контейнер и завершение цикла отрисовки (Layout/Reflow).

Выясним, как обойти эти ограничения, используя комбинированный подход: управление из кода 1С и оптимизированный JavaScript.

Решение 1: Использование обработчика ожидания в 1С

Наиболее стабильным решением, как показала практика обсуждения, является использование метода ПодключитьОбработчикОжидания. Это позволяет дать платформе и движку Chromium необходимое время (десятые доли секунды) для завершения формирования DOM-дерева. Разберем по шагам реализацию этого метода.

Сначала создадим процедуру, которая будет отвечать за установку текста и запуск таймера:


&НаКлиенте
Процедура ОбновитьЛог(ТекстHTML)
    // Устанавливаем содержимое поля
    Объект.ТекстHTMLПоля = ТекстHTML;
    
    // Даем небольшую паузу для рендеринга (0.1 - 0.2 секунды)
    ПодключитьОбработчикОжидания("ВыполнитьПрокруткуВниз", 0.1, Истина);
КонецПроцедуры

Затем опишем саму процедуру прокрутки, которая обращается к объектной модели документа непосредственно из встроенного языка 1С:


&НаКлиенте
Процедура ВыполнитьПрокруткуВниз()
    Попытка
        ДокументHTML = Элементы.ПолеHTMLДокумента.Документ;
        Если ДокументHTML <> Неопределено Тогда
            // Устанавливаем scrollTop в значение высоты всей страницы
            // Добавление большого числа (например, +9999) гарантирует скролл до самого низа
            ДокументHTML.body.scrollTop = ДокументHTML.body.scrollHeight + 9999;
        КонецЕсли;
    Исключение
        // В веб-клиенте доступ к Документ может появиться не сразу
        ПодключитьОбработчикОжидания("ВыполнитьПрокруткуВниз", 0.1, Истина);
    КонецПопытки;
КонецПроцедуры

Решение 2: Оптимизация JavaScript внутри HTML-кода

Если вы предпочитаете управлять логикой внутри самого HTML-документа, проанализируем ситуацию с выбором правильных свойств прокрутки. Современные браузеры лучше реагируют на использование метода window.scrollTo или работу с document.documentElement.

Рассмотрим пример кода, который можно вставить в конец вашего HTML-документа перед закрывающим тегом </body>:


<script>
function scrollBottom() {
    // Используем универсальный метод определения элемента прокрутки
    var scrollingElement = document.scrollingElement || document.documentElement;
    scrollingElement.scrollTop = scrollingElement.scrollHeight;
}

// Вызываем функцию через небольшую задержку после загрузки
window.onload = function() {
    setTimeout(scrollBottom, 50);
};
</script>

Важный нюанс: Использование setTimeout внутри JS часто выполняет ту же роль, что и обработчик ожидания в 1С, позволяя скрипту дождаться завершения расчетов высоты элементов движком Chromium.

Решение 3: Метод scrollIntoView (самый современный подход)

Проанализируем еще один эффективный способ — использование метода scrollIntoView. Он избавляет нас от необходимости вручную вычислять scrollHeight. Суть метода заключается в создании невидимого "якоря" в самом конце документа и программной фокусировке на нем.

Добавьте в самый конец вашего HTML-текста пустой элемент:

<div id="end-of-page"></div>

Теперь функция прокрутки в 1С или JS будет выглядеть гораздо проще:


// Пример для вызова из кода 1С
Элементы.ПолеHTMLДокумента.Документ.getElementById("end-of-page").scrollIntoView(false);

Параметр false указывает браузеру, что элемент должен быть выровнен по нижней границе видимой области, что идеально подходит для нашей задачи.

Особенности работы в веб-клиенте

Разберем ситуацию, когда решение работает в тонком клиенте, но дает сбои в браузере (веб-клиент). В веб-клиенте 1С поле HTML-документа оборачивается в iframe. Это накладывает дополнительные ограничения:

Для веб-клиента рекомендуется всегда использовать проверку на существование объекта Документ и его свойства body перед попыткой чтения высоты или установки позиции скролла.

Рекомендации по исправлению события onscroll

В новых релизах платформы (8.3.14+) событие onscroll, назначенное на тег body, также может не срабатывать. Это связано с тем, что фактическая прокрутка происходит на уровне html или контейнера с overflow: auto. Чтобы восстановить отслеживание прокрутки, попробуйте назначать обработчик на уровень window:


window.addEventListener('scroll', function() {
    // Ваш код обработки скролла
    console.log("Текущая позиция: " + window.pageYOffset);
}, true);

Использование третьего параметра true (перехват события) позволяет ловить события прокрутки, даже если они не "всплывают" стандартным образом.

Резюмируя: Для стабильной работы автопрокрутки в современных версиях 1С используйте связку из ПодключитьОбработчикОжидания на стороне 1С и метода scrollIntoView или установки scrollTop со значительным запасом (+9999) на стороне клиента. Это обеспечит корректное поведение интерфейса независимо от скорости рендеринга страницы движком Chromium.

← На главную