При работе с ПолеHTMLДокумента в среде 1С программисты часто сталкиваются с неприятной особенностью: стандартные методы получения позиции скролла, такие как window.scrollY или document.body.scrollTop, упорно возвращают «0», даже если страница прокручена далеко вниз. Это происходит из-за того, что движок браузера внутри 1С интерпретирует документ как единое полотно, а прокрутку осуществляет сам контейнер платформы, «не сообщая» об этом внутреннему JavaScript-контексту.
В этой статье мы подробно разберем, как обойти это ограничение, заставить 1С правильно считывать координаты прокрутки и восстанавливать их после обновления данных или переоткрытия формы.
Разберем ситуацию: мы пытаемся вызвать window.scrollY в обработчике события, но получаем пустое значение. Проанализируем причину. В зависимости от версии платформы и режима приложения (тонкий, толстый или веб-клиент), 1С использует разные движки рендеринга (Internet Explorer/Trident или WebKit/Chromium). В большинстве случаев встроенное поле ведет себя так, будто высота контента неограничена, и полосы прокрутки рисует сама форма 1С, а не окно браузера.
Проверим это экспериментально: если мы подписываемся на событие onscroll окна, оно просто не вызывается. Чтобы решить эту проблему, нам нужно изменить структуру HTML-документа так, чтобы прокрутка происходила внутри контролируемого нами элемента.
Самый надежный способ — это обернуть все содержимое тега body в отдельный блок div, который будет имитировать окно просмотра. Мы зададим ему высоту 100% и разрешим внутреннюю прокрутку средствами CSS. Рассмотрим, как должен выглядеть наш HTML-код.
<html>
<head>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
overflow: hidden; /* Отключаем скролл самого body */
}
#scroller {
height: 100%;
overflow-y: auto; /* Включаем вертикальный скролл для дива */
width: 100%;
}
</style>
</head>
<body>
<div id="scroller">
<!-- Здесь размещается весь ваш контент -->
<p>Много текста для появления прокрутки...</p>
</div>
</body>
</html>
Теперь, когда прокрутка происходит внутри элемента с id="scroller", мы можем легко получить его позицию через свойство scrollTop. Рассмотрим пример кода на стороне 1С, который считывает это значение.
Для того чтобы получить данные из ПолеHTMLДокумента, мы обращаемся к объектной модели документа (DOM). Выясним, как это реализовать в коде модуля формы:
& Процедура СохранитьПозициюПрокрутки()
ДокументHTML = Элементы.ПолеПросмотра.Документ;
ЭлементСкролла = ДокументHTML.getElementById("scroller");
Если ЭлементСкролла <> Неопределено Тогда
ПозицияY = ЭлементСкролла.scrollTop;
Сообщить("Текущая позиция: " + ПозицияY);
// Сохраняем это значение в реквизит формы или переменную
ПоследняяПозицияСкролла = ПозицияY;
КонецЕсли;
КонецПроцедуры
Важный момент: если вы используете современный движок (WebKit), обращение напрямую через Элементы.Поле.Документ может работать медленно или требовать асинхронного вызова через ВыполнитьJavaScript(). В этом случае лучше передавать значение из JS в 1С через механизм оповещений.
Когда данные в 1С обновились и HTML-текст был переформирован, нам нужно вернуть пользователя в ту же точку, где он находился. Проанализируем последовательность действий:
scrollTop нашего контейнера.ПолеHTMLДокумента.ДокументСформирован) устанавливаем scrollTop обратно.Посмотрим на пример установки позиции:
& Процедура ВосстановитьПозициюПрокрутки()
ДокументHTML = Элементы.ПолеПросмотра.Документ;
ЭлементСкролла = ДокументHTML.getElementById("scroller");
Если ЭлементСкролла <> Неопределено Тогда
// Устанавливаем сохраненное ранее значение
ЭлементСкролла.scrollTop = ПоследняяПозицияСкролла;
КонецЕсли;
КонецПроцедуры
Рассмотрим ситуацию, когда нам не нужно знать точные координаты в пикселях, а достаточно вернуться к определенному элементу (например, к последней просмотренной строке отчета). В этом случае удобно использовать встроенный метод JavaScript scrollIntoView().
При генерации HTML-кода добавьте уникальный id или временный класс к нужному элементу. Затем вызовите скрипт:
ТекстСкрипта = "document.getElementById('target_element').scrollIntoView({behavior: 'smooth', block: 'start'});";
Элементы.ПолеПросмотра.ВыполнитьJavaScript(ТекстСкрипта);
Этот метод более гибок, так как он автоматически учитывает размеры окна и положение элемента, избавляя нас от вычисления точных пикселей.
Если код не работает так, как ожидалось, проанализируем состояние документа через встроенный отладчик. В платформе 1С (начиная с определенных релизов 8.3) можно вызвать консоль разработчика прямо в режиме предприятия. Для этого используйте комбинацию клавиш Ctrl + Shift + Alt + F12.
В открывшейся консоли вы можете интерактивно проверить свойства объектов:
document.getElementById('scroller').scrollTop, чтобы увидеть текущее значение.document.body.clientHeight, чтобы понять, не растянулся ли документ за пределы видимости.height: 100% применились корректно.Подведем итог нашему исследованию. Для стабильной работы с прокруткой в 1С необходимо соблюдать следующие правила:
body или window. Создавайте корневой div с overflow: auto.<!DOCTYPE html> в начале документа переводит браузер в стандартный режим, что критично для правильного вычисления высот в IE-движке.Поле HTML документа установите параметр Полосы прокрутки в значение Нет, чтобы избежать эффекта «двойного скролла».Следуя этим шагам, мы обеспечим комфортную работу пользователя с динамическим контентом в 1С, сохраняя контекст его работы даже при частом обновлении данных.