autoUpdate utility

autoUpdate — это утилита библиотеки Floating UI, предназначенная для автоматического обновления позиции всплывающих элементов (флоатов) в ответ на изменения в DOM, размеры окна или скролл. Она является ключевым инструментом при создании динамических интерфейсов, где положение элементов должно корректироваться без ручного вмешательства.


Основная концепция

autoUpdate управляет динамическим пересчётом позиции элемента. Она принимает следующие параметры:

autoUpdate(reference, floating, update, options?)
  • reference — элемент-ориентир, относительно которого позиционируется всплывающий элемент.
  • floating — сам всплывающий элемент.
  • update — функция, вызываемая при необходимости пересчёта позиции.
  • options — объект с дополнительными настройками (необязательный).

Возвращает функцию stop, которую можно вызвать для прекращения автоматического обновления.


Примеры использования

Базовый пример автоматического обновления позиции:

import { autoUpdate, computePosition } from '@floating-ui/dom';

const reference = document.querySelector('#button');
const floating = document.querySelector('#tooltip');

const cleanup = autoUpdate(reference, floating, () => {
  computePosition(reference, floating, {
    placement: 'top'
  }).then(({ x, y }) => {
    Object.assign(floating.style, {
      left: `${x}px`,
      top: `${y}px`
    });
  });
});

// В случае необходимости остановки:
cleanup();

В этом примере autoUpdate следит за изменениями размера окна, скролла и DOM, и при каждом событии вызывает функцию update, где пересчитывается позиция с помощью computePosition.


Опции autoUpdate

Утилита поддерживает объект options с настройками:

  • ancestorResize (по умолчанию true) — отслеживает изменение размеров родительских элементов.
  • elementResize (по умолчанию true) — отслеживает изменение размеров самого floating-элемента.
  • layoutShift (по умолчанию true) — реагирует на сдвиги макета (например, добавление контента выше).
  • animationFrame (по умолчанию true) — обновление на каждом кадре анимации для плавных трансформаций.

Пример:

autoUpdate(reference, floating, update, {
  ancestorResize: true,
  elementResize: false,
  layoutShift: true,
  animationFrame: false
});

Управление производительностью

autoUpdate создаёт подписки на множество событий: resize, scroll, MutationObserver. При большом количестве floating-элементов это может влиять на производительность. Для оптимизации:

  1. Выключать ненужные опции:

    • Если элемент статичен по размеру, elementResize: false.
    • Если не требуется реагировать на layout shift, layoutShift: false.
  2. Использовать animationFrame выборочно:

    • Для плавных анимаций полезно оставить включённым.
    • Для статичных элементов — можно отключить.
  3. Останавливать обновления при скрытии элемента:

    const cleanup = autoUpdate(reference, floating, update);
    
    // Скрытие элемента
    floating.style.display = 'none';
    cleanup(); // освобождение ресурсов

Применение в комбинированных системах

autoUpdate идеально подходит для:

  • Всплывающих подсказок (tooltips) — автоматически корректирует положение при скролле или изменении контента.
  • Попапов и дропдаунов — гарантирует правильное позиционирование даже при динамическом изменении размеров окна.
  • Контекстных меню — обеспечивает мгновенную реакцию на изменения DOM и видимость элементов.

Комбинация с computePosition позволяет точно управлять placement, offset, shift, flip и другими middleware Floating UI:

autoUpdate(reference, floating, () => {
  computePosition(reference, floating, {
    placement: 'bottom',
    middleware: [
      offset(10),
      flip(),
      shift({ padding: 5 })
    ]
  }).then(({ x, y }) => {
    Object.assign(floating.style, { left: `${x}px`, top: `${y}px` });
  });
});

Важные нюансы

  • autoUpdate не сохраняет предыдущие позиции — каждый вызов update полностью пересчитывает координаты.
  • Поддерживает динамическое добавление элементов в DOM — через MutationObserver автоматически отслеживает изменения.
  • Рекомендуется всегда вызывать возвращаемую функцию stop при удалении floating-элемента, чтобы избежать утечек памяти.

autoUpdate является ядром динамического позиционирования в Floating UI, обеспечивая надёжное и эффективное обновление координат для любых интерактивных элементов. Правильное использование опций позволяет балансировать между точностью позиционирования и производительностью, особенно в сложных интерфейсах с множеством всплывающих элементов.