Блог разработчика 1С-Битрикс

Управление DOM-структурой в 1С-Битрикс: глубокий разбор BX.scrollToNode

Плавная прокрутка к нужному элементу ― классический приём для улучшения UX. В ядре 1С-Битрикс уже есть готовый метод BX.scrollToNode, который избавляет от ручного расчёта координат и кросс-браузерных хаков. В статье разберём сигнатуру функции, приведём типовые и нетиповые кейсы, подскажем, какие ошибки встречаются чаще всего и как их избежать.

Управление DOM-структурой. BX.scrollToNode

Что делает BX.scrollToNode

BX.scrollToNode(
    DOMNode node // Обязательный параметр: DOM-элемент, к которому нужно прокрутиться
);

Метод анимирует прокрутку окна браузера (или ближайшего скроллируемого контейнера ― об этом ниже) так, чтобы верхняя граница указанных нод оказалась вверху видимой области. Алгоритм учитывает отступы документа и работает во всех актуальных браузерах, поддерживаемых ядром Битрикса.


Минимальный рабочий пример

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <title>BX.scrollToNode — базовый пример</title>
    <script src="/bitrix/js/main/core/core.js"></script> <!-- ядро Битрикса -->
    <style>
        body {margin: 0;}
        header, footer {height: 100vh; display:flex; align-items:center; justify-content:center;}
        header {background:#e3f2fd;}
        footer {background:#ffecb3;}
        #scroll-btn{
            cursor:pointer; margin:1rem auto; padding:.7rem 1.2rem;
            background:#607d8b; color:#fff; border:none; border-radius:.5rem;
            box-shadow:0 2px 8px rgba(0,0,0,.25); font-size:1rem;
        }
    </style>
</head>
<body>
<header>
    <button id="scroll-btn">Прокрутить к футеру</button>
</header>
<footer id="footer">
    <h2>Вы добрались до футера </h2>
</footer>
<script>
BX.ready(function () {
    BX.bind(BX('scroll-btn'), 'click', function () {
        BX.scrollToNode(BX('footer'));
    });
});
</script>
</body>
</html>

Что важно

  • Подключаем ядро: скрипт /bitrix/js/main/core/core.js уже содержит метод BX.scrollToNode.
  • Используем BX.ready для гарантии, что DOM загружен.
  • Передаём именно DOM-узел, а не строковый id или jQuery-объект.

Расширенные сценарии

1. Автопрокрутка к якорю из URL при загрузке страницы

<script>
BX.ready(function () {
    var hash = location.hash.replace('#', '');
    if (hash) {
        var target = BX(hash);
        if (BX.type.isDomNode(target)) {
            BX.scrollToNode(target);
        }
    }
});
</script>

Используйте, если хотите плавно прокручивать к секциям «FAQ», «Отзывы» и т.д., когда пользователь переходит по ссылке вида site.ru/page#reviews.

2. Форма с ошибками валидации

function highlightErrors(errors){
    if (!errors.length) return;
    // прокручиваем к первой ошибке
    BX.scrollToNode(errors[0].node);
    // выделяем все поля с ошибкой красной рамкой
    errors.forEach(function(err){
        BX.addClass(err.node, 'error-field');
        BX.adjust(err.node, {attrs:{title: err.message}});
    });
}

errors — массив объектов {node: DOMNode, message: String}. При получении ответа от серверного компонента вызываем highlightErrors(errors).

3. Прокрутка внутри кастомного overflow: auto контейнера

.scroll-box{
    max-height:300px;
    overflow:auto;
    border:1px solid #ccc;
    padding:1rem;
}
<div id="dialog" class="scroll-box">
    <!-- длинный список сообщений -->
    <div id="msg-123" class="message highlighted">Новое сообщение</div>
</div>
BX.ready(function(){
    BX.scrollToNode(BX('msg-123')); // (!) Метод сам найдёт ближайший скроллируемый родитель
});

Лайфхак: Если нужно насильно прокрутить именно окно браузера, а не контейнер, используйте комбинацию:

BX.scrollToNode(BX('msg-123'), 0, document.body);

(Второй аргумент — смещение, третий — нода-контейнер.)

4. «Прокрутка + подсветка» в комплексном компоненте

BX.ready(function () {
    BX.bindDelegate(document.body, 'click', {className: 'js-goto-card'}, function () {
        var id = this.getAttribute('data-card');
        var card = BX('card-' + id);
        if (!card) return;
        BX.scrollToNode(card);
        // плавно подсветим карточку после скролла
        BX.addClass(card, 'blink');
        setTimeout(function(){ BX.removeClass(card, 'blink'); }, 2000);
    });
});
.blink{
    animation: blink-bg 2s ease-in-out;
}
@keyframes blink-bg{
    0%{background:#fff799;}
    100%{background:transparent;}
}

Частые ошибки и как их исправить

Ошибка Как проявляется Исправление
Передаёте строку id BX.scrollToNode('footer') молча не работает Оборачивайте в BX() или document.getElementById
Отсутствует элемент JS-ошибка Cannot read property Проверяйте через BX.type.isDomNode
Скролл внутри iframe Страница не прокручивается Вызывайте из контента, а не из родительского окна, или прокручивайте parent
Модуль main не подключён BX is not defined Добавьте <script src="/bitrix/js/main/core/core.js"></script>

Производительность и UX-советы

  1. Не вызывайте BX.scrollToNode чаще 60 раз в секунду – это анимация, а не подслушивающий скрипт. Для частых вызовов (например, авто-чат) ставьте debounce.
  2. Добавляйте плавную подсветку целевого блока, чтобы пользователь понял, куда его прокрутило.
  3. Сохраняйте положение в sessionStorage, если нужно возвращаться к той же секции после перезагрузки.
  4. Учитывайте фиксированные шапки. В ядре нет автоматического offset’а; добавьте отступ самостоятельно:
var headerHeight = 80;
BX.scrollToNode(node, headerHeight);

Совместимость ядра

Метод появился в ядре main версии ≥ 14.5. В корпоративном портале и Битрикс24 работает из коробки. Для редких проектов на старых сборках можно добавить полифилл:

if (!BX.scrollToNode){
    BX.scrollToNode = function(node, offset){
        if (!BX.type.isDomNode(node)) return;
        var top = BX(node).getBoundingClientRect().top + window.pageYOffset - (offset || 0);
        window.scrollTo({top: top, behavior:'smooth'});
    };
}

Заключение

BX.scrollToNode — лаконичный, но крайне полезный метод, который позволяет быстро внедрить плавную прокрутку без сторонних библиотек. Используйте его для улучшения юзабилити форм, модальных окон, длинных лендингов и любого интерактивного контента, где важно переместить пользователя к нужной секции. Соблюдайте простые правила ― передавайте реальный DOM-узел, проверяйте его существование и учитывайте фиксированные элементы интерфейса ― и скролл будет работать безупречно. Happy coding!

Теги:  BX.scrollToNode, DOM, прокрутка, UX, JavaScript, веб-разработка


Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Разработка корпоративного сайта

от 7 дней

от 40 000 рублей

Разработка сайта без системы оплаты заказов через корзину

* стоимость зависит от наличия верстки, использования готового решения и т.д.

Участие в проекте

привлечение в проект на part-time основе

от 20 000 рублей / неделя

Возможно участие в проекте на ежедневной основе, как разработчика. Занятость - до 20 часов в неделю
Минимальный срок - одна неделя.

* сумма фиксированная

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

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.