В браузере прокрутка страницы управляется свойством
scrollTop у корневых элементов документа. В разных
браузерах это может быть либо document.documentElement,
либо document.body, поэтому при ручной анимации обычно
используются оба элемента одновременно.
Библиотека Velocity.js упрощает задачу, предоставляя встроенную
команду "scroll", которая корректно обрабатывает различия
между браузерами и позволяет задавать анимацию прокрутки как обычную
анимацию свойств.
Основной принцип: элемент прокрутки анимируется так же, как и любые другие CSS-свойства.
Наиболее распространённый сценарий — прокрутка страницы к определённому DOM-элементу.
$(".target-section").velocity("scroll", {
duration: 800
});
При таком вызове библиотека автоматически вычисляет позицию элемента относительно документа и плавно прокручивает страницу до него.
Внутри используется вычисление смещения через
offset().top, после чего значение применяется к
scrollTop.
Часто требуется учитывать фиксированные элементы интерфейса, такие
как навигационные панели. В этом случае применяется параметр
offset.
$(".target-section").velocity("scroll", {
duration: 700,
offset: -60
});
Отрицательное значение сдвигает конечную точку прокрутки выше, что позволяет компенсировать высоту фиксированного header.
Положительное значение, наоборот, останавливает прокрутку ниже элемента.
Velocity.js предоставляет детализированное управление анимацией через параметры:
duration — длительность в миллисекундахeasing — функция сглаживанияqueue — управление очередью анимацийПример с кастомной плавностью:
$(".target-section").velocity("scroll", {
duration: 1200,
easing: "easeInOutCubic"
});
Использование сложных easing-функций позволяет добиться более естественного движения, особенно в интерфейсах с большим количеством навигации.
Помимо привязки к элементу, возможна прокрутка к числовому значению пикселей:
$.velocity("scroll", {
offset: 500,
duration: 600
});
Или через явное указание контейнера:
$("html, body").velocity({
scrollTop: 1000
}, {
duration: 800
});
В этом случае анимация выполняется напрямую через свойство
scrollTop.
При наличии фиксированных элементов интерфейса (header, sticky menu, toolbar) возникает проблема перекрытия целевого блока.
Типовой подход — вычисление динамического offset:
var headerHeight = $(".header").outerHeight();
$(".target-section").velocity("scroll", {
duration: 900,
offset: -headerHeight
});
Такой подход позволяет адаптировать поведение прокрутки под изменяющуюся высоту интерфейса, например при responsive-дизайне.
Velocity.js поддерживает работу не только с документом, но и с прокручиваемыми контейнерами.
$(".container").velocity("scroll", {
container: $(".container"),
duration: 600
});
Контейнер должен иметь CSS-свойство overflow: auto или
scroll. В этом режиме прокрутка ограничивается внутренней
областью блока, а не всей страницей.
Прокрутка может быть частью цепочки анимаций, где сначала выполняется действие, затем происходит переход к секции.
$(".button").on("click", function () {
$(".overlay").velocity({ opacity: 0 }, { duration: 300 })
.velocity("scroll", {
duration: 700,
offset: -50
});
});
Velocity.js сохраняет очередность выполнения, если не отключена
очередь через queue: false.
При взаимодействии пользователя с интерфейсом часто требуется прерывать текущую анимацию прокрутки.
$("html, body").velocity("stop");
Это останавливает текущую анимацию и предотвращает конфликт между пользовательским скроллом и программной прокруткой.
При частом вызове прокрутки (например, при кликах по меню навигации) важно учитывать конкуренцию анимаций.
Используются подходы:
$("html, body").velocity("stop").velocity("scroll", {
duration: 500,
offset: -80
});
Такой паттерн гарантирует, что предыдущая анимация будет отменена перед запуском новой.
В одностраничных приложениях прокрутка к элементам часто используется при смене маршрутов.
function navigateTo(section) {
$(section).velocity("scroll", {
duration: 0,
offset: -70
});
}
Нулевая или минимальная длительность применяется для мгновенного позиционирования при инициализации нового состояния интерфейса.
Если элементы создаются асинхронно, прокрутка должна выполняться после завершения DOM-обновления.
loadContent(function () {
$(".new-section").velocity("scroll", {
duration: 800
});
});
В противном случае вычисленная позиция может оказаться некорректной из-за отсутствия элемента в момент расчёта.
Velocity.js опирается на координаты
getBoundingClientRect и offset. Однако при
сложной верстке (flex, transform, nested scroll) возможны
расхождения.
В таких случаях применяется ручное уточнение:
var top = $(".target").offset().top;
$("html, body").velocity({
scrollTop: top - 100
}, {
duration: 700
});
На мобильных устройствах поведение прокрутки может отличаться из-за аппаратного ускорения и нативных жестов.
Velocity.js автоматически использует оптимизированные механизмы анимации, однако при конфликте с touch-scroll возможны рывки. В таких сценариях рекомендуется уменьшать длительность анимации и избегать чрезмерно длинных переходов.
Прокрутка часто используется вместе с изменением прозрачности, масштаба и позиции элементов.
$(".card")
.velocity({ opacity: 0.5 }, { duration: 300 })
.velocity("scroll", { duration: 700 })
.velocity({ opacity: 1 }, { duration: 300 });
Такая последовательность позволяет создавать визуально связные переходы между состояниями интерфейса.
Velocity.js поддерживает именованные очереди, что позволяет разделять прокрутку и другие эффекты.
$(".section").velocity("scroll", {
duration: 800,
queue: "navigation"
});
Это предотвращает конфликт анимаций, выполняемых параллельно в разных частях интерфейса.
При навигации по длинным страницам важно минимизировать нагрузку на браузер. Рекомендуется:
stopdurationfunction scrollToSection(selector) {
$("html, body").velocity("stop").velocity("scroll", {
duration: 600,
offset: -70
});
}
Часто прокрутка привязывается к кликам по навигационным ссылкам:
$("nav a").on("click", function (e) {
e.preventDefault();
var target = $(this).attr("href");
$(target).velocity("scroll", {
duration: 900,
offset: -80
});
});
Такой подход заменяет стандартное поведение якорей и обеспечивает плавный переход между секциями.