Событие DOMLoaded

Lottie Web строит жизненный цикл анимации поверх JSON-описания, и одним из ключевых моментов инициализации является момент, когда экземпляр анимации завершает подготовку DOM-структуры, необходимых контейнеров и внутренних слоёв. В этот момент становится доступным событие DOMLoaded, фиксирующее завершение привязки и разметки анимации внутри выбранного DOM-элемента.

Процесс создания анимации в Lottie Web можно разделить на несколько этапов:

  1. Инициализация экземпляра через lottie.loadAnimation
  2. Загрузка JSON-данных анимации
  3. Построение внутренних слоёв и DOM-структуры
  4. Привязка канваса или SVG к контейнеру
  5. Срабатывание DOMLoaded
  6. Последующие события: data_ready, enterFrame, complete

DOMLoaded находится между этапом построения DOM и полной готовностью данных к воспроизведению. Важно понимать, что на момент DOMLoaded данные анимации уже могут быть частично загружены, но визуальная структура в контейнере уже создана.

Смысл события DOMLoaded

DOMLoaded сигнализирует о том, что:

  • создан корневой контейнер анимации внутри указанного DOM-элемента
  • добавлены SVG-элементы или canvas-структуры (в зависимости от renderer)
  • произведена первичная компоновка слоёв
  • DOM-узлы анимации доступны для манипуляций через API

На этом этапе ещё не гарантируется завершённая загрузка всех ресурсов, таких как изображения или внешние ассеты, если они используются в композиции.

Регистрация обработчика DOMLoaded

Событие доступно через метод addEventListener экземпляра анимации:

const animation = lottie.loadAnimation({
  container: document.getElementById('anim'),
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: 'animation.json'
});

animation.addEventListener('DOMLoaded', () => {
  console.log('DOM структура анимации построена');
});

Ключевой момент заключается в том, что обработчик регистрируется на экземпляре анимации, а не на глобальном объекте. Это отличает DOMLoaded от стандартных DOM-событий браузера.

Отличие DOMLoaded от DOMContentLoaded

Несмотря на схожесть названия, DOMLoaded в Lottie Web не имеет прямого отношения к браузерному событию DOMContentLoaded.

Характеристика DOMContentLoaded (браузер) DOMLoaded (Lottie Web)
Область Документ HTML Экземпляр анимации
Триггер Построение DOM страницы Построение DOM анимации
Контекст Глобальный Локальный (animation instance)
Назначение Готовность страницы Готовность структуры анимации

DOMLoaded не зависит от загрузки всей страницы и может срабатывать многократно при создании нескольких анимаций.

Практическое значение DOMLoaded

DOMLoaded используется для задач, где требуется доступ к DOM-элементам анимации до начала воспроизведения или сразу после инициализации структуры.

Типичные сценарии:

  • модификация SVG-элементов до старта анимации
  • добавление кастомных классов к слоям
  • измерение размеров элементов анимации
  • синхронизация внешних UI-компонентов с появлением DOM анимации

Пример доступа к внутреннему SVG после построения:

animation.addEventListener('DOMLoaded', () => {
  const svg = animation.container.querySelector('svg');
  svg.setAttribute('preserveAspectRatio', 'xMidYMid slice');
});

Особенности работы с SVG-рендерером

При использовании renderer: 'svg' DOMLoaded особенно важен, так как именно в этот момент создаётся SVG-дерево. Все слои, маски и группы превращаются в DOM-узлы.

При этом структура может быть глубокой и вложенной:

  • <svg>

    • <g> (группы слоёв)
    • <path> (векторные формы)
    • <clipPath> (маски)
    • <image> (внешние ресурсы)

DOMLoaded гарантирует, что эта структура уже существует, но не гарантирует завершённую загрузку внешних изображений.

Поведение при Canvas-рендерере

При использовании renderer: 'canvas' DOMLoaded имеет более условный характер. DOM-структура в привычном смысле отсутствует, однако событие всё равно срабатывает после создания canvas-элемента и привязки его к контейнеру.

lottie.loadAnimation({
  container: document.getElementById('anim'),
  renderer: 'canvas',
  loop: true,
  autoplay: true,
  path: 'animation.json'
}).addEventListener('DOMLoaded', () => {
  console.log('Canvas готов к отрисовке');
});

В этом случае DOMLoaded означает готовность canvas-контекста и внутреннего рендера, а не DOM-узлов SVG.

Порядок срабатывания событий

Типичный порядок событий в Lottie Web:

  1. data_ready — JSON-анимация загружена и распарсена
  2. DOMLoaded — DOM или canvas структура создана
  3. enterFrame — начинается покадровая анимация
  4. loopComplete — завершение цикла (если loop включён)
  5. complete — финальное завершение (если loop выключен)

DOMLoaded часто является точкой, после которой можно безопасно вмешиваться в структуру анимации без риска отсутствующих элементов.

Частые ошибки при использовании DOMLoaded

Одной из распространённых ошибок является попытка доступа к DOM анимации до срабатывания события:

const svg = animation.container.querySelector('svg'); // может быть null

Правильный подход:

animation.addEventListener('DOMLoaded', () => {
  const svg = animation.container.querySelector('svg');
});

Другой ошибкой является ожидание полной загрузки всех ассетов. DOMLoaded не покрывает загрузку изображений внутри композиции.

Взаимодействие с динамическими контейнерами

При повторной инициализации анимации внутри одного и того же DOM-элемента DOMLoaded может срабатывать каждый раз при пересоздании экземпляра. Это важно при SPA-архитектурах, где компоненты монтируются и размонтируются.

function mountAnimation() {
  const anim = lottie.loadAnimation({
    container: document.getElementById('anim'),
    renderer: 'svg',
    path: 'anim.json'
  });

  anim.addEventListener('DOMLoaded', () => {
    console.log('новая анимация готова');
  });

  return anim;
}

Внутренняя роль DOMLoaded в архитектуре Lottie Web

С точки зрения внутренней реализации DOMLoaded является маркером завершения сборки визуального дерева. Он отделяет фазу парсинга данных от фазы исполнения анимации. Это позволяет:

  • разделять загрузку и рендер
  • безопасно применять пост-обработку DOM
  • синхронизировать внешние скрипты с визуальной готовностью

DOMLoaded выступает технической точкой синхронизации между движком анимации и браузерным DOM или canvas-слоем, обеспечивая предсказуемость дальнейших операций над экземпляром анимации.