При разработке интерфейсов на платформе 1С, использующих Поле HTML документа (например, для реализации чатов, ленты уведомлений или истории переписки), программисты часто сталкиваются с задачей автоматического позиционирования. По умолчанию документ открывается в верхней части, в то время как пользователю важнее сразу видеть последние записи, расположенные внизу. В этой статье мы подробно разберем, как реализовать автоматическую прокрутку, почему стандартные методы могут не срабатывать и как адаптировать решение под современные движки Chromium и WebKit.
Прежде чем переходить к коду, давайте проанализируем ситуацию. Почему простая установка свойств или имитация нажатия клавиш через WScript.Shell часто не дает результата? Основная причина кроется в особенностях работы встроенных браузеров. Когда мы назначаем текст или навигацию полю HTML, документ строится не мгновенно. Объектная модель (DOM) перестраивается в фоновом режиме, и в момент выполнения кода 1С высота документа может быть еще нулевой или неполной. Если мы попытаемся прокрутить страницу до того, как она отрисована, команда просто уйдет «в никуда».
Рассмотрим основные способы решения этой задачи, начиная от проверенных временем и заканчивая современными методами.
Как показывает практика и обсуждения на форумах, наиболее стабильным решением является использование обработчика ожидания. Это позволяет дать движку браузера необходимые миллисекунды для завершения рендеринга. Разберем этот алгоритм по шагам.
Во-первых, при открытии формы или после обновления текста HTML необходимо инициировать задержку. Для этого воспользуемся методом ПодключитьОбработчикОжидания. Во-вторых, в самой процедуре прокрутки крайне важно проверять состояние готовности документа через свойство readyState.
Рассмотрим пример кода:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Инициируем прокрутку с небольшой задержкой (0.1 сек)
ПодключитьОбработчикОжидания("ВыполнитьПрокруткуHTML", 0.1, Истина);
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьПрокруткуHTML()
ПолеHTML = Элементы.ПредпросмотрHTMLБезВложений;
// Проверяем, сформирован ли документ
Если ПолеHTML.Документ <> Неопределено Тогда
ДокументHTML = ПолеHTML.Документ;
// Значение "complete" означает, что DOM-дерево полностью построено
Если ДокументHTML.readyState = "complete" Тогда
// Устанавливаем scrollTop равным максимальной высоте контента
// Добавление 9999 гарантирует попадание в самый низ
ДокументHTML.body.scrollTop = ДокументHTML.body.scrollHeight + 9999;
Иначе
// Если документ еще не готов, перезапускаем ожидание
ПодключитьОбработчикОжидания("ВыполнитьПрокруткуHTML", 0.1, Истина);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важное замечание: Не используйте пустые циклы Пока ... Цикл для ожидания готовности readyState. Это приведет к зависанию всего приложения 1С, так как поток сообщений системы будет заблокирован, и браузер так и не сможет завершить загрузку документа.
Если ваша платформа 1С использует современный движок (Chromium), мы можем задействовать более элегантные методы JavaScript через объект DefaultView. Рассмотрим использование метода scrollIntoView, который позволяет прокрутить экран к конкретному элементу.
Для этого в самом конце вашего HTML-кода добавьте пустой тег-идентификатор:
<div id="bottom-marker"></div>
После этого из кода 1С можно вызвать прокрутку к этому маркеру:
&НаКлиенте
Процедура ПрокрутитьКМаркеру()
Документ = Элементы.ПредпросмотрHTMLБезВложений.Документ;
Если Документ <> Неопределено Тогда
// Используем современный метод прокрутки
Элемент = Документ.getElementById("bottom-marker");
Если Элемент <> Неопределено Тогда
Элемент.scrollIntoView(Ложь); // Параметр Ложь прижимает элемент к низу
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Преимущество scrollIntoView заключается в том, что он работает более интеллектуально и учитывает границы видимости контейнера.
Проанализируем еще один надежный вариант, который часто применяется в веб-разработке и отлично подходит для Поля HTML документа в 1С. Это прямой вызов функции прокрутки окна. Выполнить его можно через обращение к DefaultView (аналог window в браузере).
&НаКлиенте
Процедура ПрокруткаЧерезJS()
Поле = Элементы.ПредпросмотрHTMLБезВложений;
Если Поле.Документ <> Неопределено И Поле.Документ.DefaultView <> Неопределено Тогда
// Вызываем JS метод scrollTo
// Первый параметр - X, второй - Y (высота всего документа)
Поле.Документ.DefaultView.scrollTo(0, Поле.Документ.body.scrollHeight);
КонецЕсли;
КонецПроцедуры
Выясним, на что стоит обратить внимание при выборе метода в зависимости от условий эксплуатации системы:
scrollTop и offsetHeight.Документ.window.onload непосредственно в текст HTML будет самым надежным решением.Если вы сами формируете HTML для вывода переписки, рассмотрим «хитрый» способ на уровне CSS. Можно использовать свойство flex-direction: column-reverse для контейнера сообщений. В этом случае элементы будут физически располагаться в коде сверху вниз, но визуально отображаться снизу вверх. Это автоматически удерживает фокус пользователя в нижней части области при добавлении новых данных, так как «дно» списка становится его началом. Для подготовки и интерактивной отладки разметки подойдёт обработка для редактирования HTML в управляемом интерфейсе.
Подведем итог: для реализации качественного позиционирования в 1С используйте комбинацию из обработчика ожидания, проверки readyState и установки scrollTop или метода scrollIntoView. Это обеспечит стабильную работу интерфейса вне зависимости от скорости загрузки содержимого.