Библиотека AOS (Animate on Scroll) предназначена для
запуска анимаций элементов при их появлении в области видимости окна
браузера. В стандартном сценарии, когда страница загружается полностью,
инициализация выполняется один раз с помощью функции
AOS.init(). Однако в современных SPA-приложениях (Single
Page Application) с использованием роутинга возникает особенность:
переход между “страницами” не сопровождается полной перезагрузкой
документа, а значит, многие элементы добавляются в DOM после
первоначальной инициализации AOS. В этом случае стандартного вызова
AOS.init() недостаточно для корректного запуска анимаций на
новых элементах.
Новые элементы в DOM не анимируются При динамическом рендеринге новых страниц элементы, появляющиеся после первой инициализации AOS, не получают обработчики и классы, необходимые для анимаций.
Повторная анимация старых элементов Если не
учитывать текущий статус элементов, повторный вызов
AOS.init() может неправильно обработать уже анимированные
блоки или вызвать конфликт классов.
Отсутствие автоматического обновления AOS не отслеживает изменения DOM самостоятельно — требуется явный вызов метода обновления для пересчета позиций и активации новых элементов.
Библиотека предоставляет несколько подходов для корректной работы с динамически изменяющимся контентом.
AOS.init({
once: true,
duration: 800
});
Если SPA использует роутинг, необходимо повторно вызывать
AOS.init() после загрузки нового компонента или
маршрута.
Недостаток: стандартный вызов может перезаписать уже
анимированные элементы, если не установлен параметр
once: true.
AOS.refresh()// После изменения DOM
AOS.refresh();
Метод refresh() пересчитывает позиции всех элементов с
атрибутом data-aos и применяет анимации к новым блокам без
повторного применения к старым. Этот метод оптимален для SPA.
Пример с роутером Vue.js:
import AOS from 'aos';
import 'aos/dist/aos.css';
export default {
watch: {
'$route'(to, from) {
this.$nextTick(() => {
AOS.refresh();
});
}
}
}
Здесь используется this.$nextTick() для того, чтобы
убедиться, что новые элементы полностью отрисованы в DOM до вызова
AOS.refresh().
AOS.refreshHard()AOS.refreshHard();
refreshHard() полностью пересоздаёт внутренние данные
AOS, включая удаление и повторное создание всех обработчиков.
Рекомендуется использовать только при крупных изменениях DOM, так как
этот метод более затратный по производительности.
Для корректной работы анимаций в приложениях с роутингом рекомендуется установить следующие параметры при инициализации:
AOS.init({
disable: 'mobile', // Отключение анимаций на мобильных устройствах для производительности
once: true, // Элемент анимируется только один раз
mirror: false, // Элемент не будет анимироваться при скролле назад
duration: 700, // Длительность анимации
easing: 'ease-in-out'
});
once: true предотвращает повторное срабатывание
анимаций на уже просмотренных элементах.mirror: false предотвращает повторную анимацию при
прокрутке вверх, что снижает нагрузку на браузер.AOS.refresh() внутри
useEffect, который зависит от изменения маршрута:import { useEffect } from 'react';
import AOS from 'aos';
import 'aos/dist/aos.css';
import { useLocation } from 'react-router-dom';
function App() {
const location = useLocation();
useEffect(() => {
AOS.init({ once: true, duration: 700 });
AOS.refresh();
}, [location.pathname]);
return <Routes>...</Routes>;
}
Vue.js Как показано выше, использовать
watch на $route с вызовом
AOS.refresh() после полной отрисовки компонента.
Angular В Angular рекомендуется использовать хук
ngAfterViewInit() или подписку на событие маршрута
NavigationEnd:
import { Component, AfterViewInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import AOS from 'aos';
@Component({...})
export class AppComponent implements AfterViewInit {
constructor(private router: Router) {}
ngAfterViewInit() {
AOS.init({ once: true, duration: 700 });
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
setTimeout(() => AOS.refresh(), 0);
}
});
}
}
setTimeout гарантирует, что DOM полностью обновлен перед
пересчетом позиций.
AOS.refresh() для динамически добавляемого
контента.AOS.init() после каждого
роутинга — лучше инициализировать один раз и использовать
refresh().AOS.refresh() с виртуальным скроллингом, чтобы
минимизировать перерисовку.once и mirror для контроля
повторных анимаций и производительности.Обновление анимаций при смене роутов является ключевым моментом для SPA, позволяя поддерживать плавные и корректные эффекты без перезагрузки страницы.