Функция getElementRects в библиотеке Floating UI
отвечает за вычисление геометрии двух ключевых элементов:
Результатом работы функции является набор прямоугольников
(DOMRect-подобных структур), описывающих размеры и
координаты этих элементов в единой системе координат.
getElementRects является частью платформенно-зависимого
адаптера (platform), который передаётся в
computePosition. Сигнатура функции:
type GetElementRects = (args: {
reference: Element | VirtualElement;
floating: HTMLElement;
strategy: 'absolute' | 'fixed';
}) => Promise<{
reference: Rect;
floating: Rect;
}>;
Где:
Rect — объект с полями:
{
x: number;
y: number;
width: number;
height: number;
}Для обычного DOM-элемента используется:
element.getBoundingClientRect()
Но Floating UI нормализует результат:
Rectfixed или
absolute)Особенность:
display: none или position)Поэтому:
Базовая реализация (упрощённая):
const platform = {
async getElementRects({reference, floating, strategy}) {
const referenceRect = reference.getBoundingClientRect();
const floatingRect = floating.getBoundingClientRect();
return {
reference: {
x: referenceRect.x,
y: referenceRect.y,
width: referenceRect.width,
height: referenceRect.height,
},
floating: {
x: floatingRect.x,
y: floatingRect.y,
width: floatingRect.width,
height: floatingRect.height,
},
};
}
};
Параметр strategy влияет на систему координат:
absolutefixedposition: fixedgetElementRects должен учитывать это различие, иначе
позиционирование будет некорректным.
Floating UI поддерживает виртуальные элементы — объекты, не являющиеся DOM-узлами, но имеющие метод:
getBoundingClientRect()
Пример:
const virtualElement = {
getBoundingClientRect() {
return {
x: 100,
y: 200,
width: 0,
height: 0,
top: 200,
left: 100,
right: 100,
bottom: 200,
};
}
};
getElementRects должен работать с такими объектами так
же, как с обычными элементами.
Floating UI использует единый формат:
x, y вместо left,
topЭто позволяет:
display: none)getBoundingClientRect() возвращает:
width = 0
height = 0
Решение:
visibility: hidden вместо
display: noneРешение:
getElementRects возвращает Promise, потому
что:
Floating UI позволяет полностью заменить механизм измерения:
const customPlatform = {
async getElementRects(args) {
// кастомная логика
}
};
Используется, когда:
getBoundingClientRect() уже учитывает CSS
transform, но:
Floating UI не устраняет это полностью, поэтому важно:
getElementRects — один из ключевых этапов в
computePosition:
getElementRectsОшибка на этапе getElementRects приводит к:
Частые вызовы могут вызывать layout thrashing. Рекомендуется:
computePositionResizeObserver и
IntersectionObserverimport {computePosition} from '@floating-ui/dom';
const button = document.querySelector('#button');
const tooltip = document.querySelector('#tooltip');
computePosition(button, tooltip).then(({x, y}) => {
Object.assign(tooltip.style, {
left: `${x}px`,
top: `${y}px`,
});
});
Внутри:
getElementRectsbutton и tooltipRect)display: none для floating-элементаfixedgetElementRects выполняет фундаментальную задачу:
Это делает библиотеку гибкой и независимой от конкретной среды выполнения.