Tippy.js поддерживает работу с виртуальными элементами, что позволяет создавать тултипы и всплывающие подсказки не только для обычных DOM-узлов, но и для объектов, которые не присутствуют напрямую в DOM. Это особенно полезно для динамических интерфейсов, кастомных canvas-рендеров или интерактивных SVG-графиков, где стандартный DOM-селектор использовать невозможно.
Виртуальный элемент в Tippy.js представляет собой объект с двумя обязательными свойствами:
const virtualElement = {
getBoundingClientRect: () => DOMRect,
clientWidth: number,
clientHeight: number
};
DOMRect, описывающий позицию и размеры виртуального
элемента.Эти свойства позволяют Tippy.js рассчитывать позицию тултипа точно так же, как для обычного DOM-элемента.
Простейший пример создания виртуального элемента для тултипа:
const virtualButton = {
getBoundingClientRect: () => ({
top: 100,
left: 200,
right: 250,
bottom: 130,
width: 50,
height: 30
}),
clientWidth: 50,
clientHeight: 30
};
tippy(virtualButton, {
content: 'Тултип для виртуального элемента',
placement: 'right'
});
В этом примере тултип будет отображаться в позиции, заданной вручную
через координаты top, left, width
и height.
Для элементов, которые обновляются в процессе работы приложения, виртуальные элементы позволяют динамически обновлять координаты:
let mouseX = 0;
let mouseY = 0;
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
const virtualCursor = {
getBoundingClientRect: () => ({
top: mouseY,
left: mouseX,
right: mouseX,
bottom: mouseY,
width: 0,
height: 0
}),
clientWidth: 0,
clientHeight: 0
};
tippy(virtualCursor, {
content: 'Следящий за курсором тултип',
placement: 'top',
followCursor: true
});
Здесь тултип привязан к позиции курсора мыши, даже если самого
элемента в DOM нет. Благодаря followCursor: true Tippy.js
корректно отслеживает перемещение.
SVG-элементы и canvas-графика часто не имеют стандартных размеров для прямого привязывания тултипов. Виртуальные элементы решают эту проблему:
const svgPoint = { x: 150, y: 75 };
const virtualSVGElement = {
getBoundingClientRect: () => ({
top: svgPoint.y,
left: svgPoint.x,
right: svgPoint.x,
bottom: svgPoint.y,
width: 0,
height: 0
}),
clientWidth: 0,
clientHeight: 0
};
tippy(virtualSVGElement, {
content: 'Информация о точке на SVG',
placement: 'bottom'
});
Таким образом можно создавать интерактивные подсказки для отдельных точек графика или элементов SVG без создания лишних DOM-узлов.
Поскольку виртуальные элементы не связаны напрямую с DOM, необходимо обновлять позицию при изменении размеров окна или контейнера:
window.addEventListener('resize', () => {
tippyInstance.popperInstance.update();
});
Метод update() заставляет Tippy.js пересчитать позицию
тултипа, используя текущие координаты виртуального элемента.
debounce
или requestAnimationFrame, чтобы избежать лишних
перерасчетов.getBoundingClientRect,
так как она вызывается при каждом рендере тултипа.tippy.show() и tippy.hide() работают с
виртуальными элементами точно так же, как с DOM-узлами.tippy.setProps({ content: 'новый контент' }) позволяет
динамически менять содержимое тултипа.tippy.popperInstance предоставляет доступ к
Popper.js-инстансу для тонкой настройки позиционирования.Виртуальные элементы делают Tippy.js универсальным инструментом для интерактивных и нестандартных интерфейсов, расширяя возможности стандартного DOM-позиционирования. Их гибкость позволяет создавать сложные и динамичные UI-сценарии без необходимости создавать лишние элементы в HTML.