Динамическое добавление элементов

Tippy.js позволяет создавать всплывающие подсказки (tooltips) и элементы всплывающего контента с гибкой настройкой позиционирования и поведения. Одной из мощных возможностей библиотеки является работа с динамически добавляемыми элементами на странице. Рассмотрим эту тему подробно.


Основы работы с динамическими элементами

Когда элементы создаются после первоначальной загрузки страницы (например, через JavaScript или AJAX), стандартная инициализация Tippy.js на существующих элементах не охватывает новые. Чтобы всплывающие подсказки корректно отображались на таких элементах, применяются следующие подходы:

  1. Делегирование событий (delegate) Метод tippy.delegate() позволяет назначать всплывающие подсказки на элементы, которые могут появиться позже. Делегирование работает через контейнер и CSS-селектор:

    tippy.delegate(document.body, {
      target: '.dynamic-button',
      content: 'Динамический элемент',
      placement: 'top',
      delay: [100, 100],
    });
    • target — CSS-селектор элементов внутри указанного контейнера.
    • content — текст или функция, возвращающая содержимое подсказки.
    • placement — позиция подсказки относительно элемента.
    • delay — задержка показа и скрытия подсказки.

    Такой подход позволяет автоматически применять подсказки ко всем новым элементам, соответствующим селектору .dynamic-button.


Использование функции content для динамического содержимого

content может быть функцией, что особенно полезно для динамических данных:

tippy.delegate(document.body, {
  target: '.dynamic-item',
  content(reference) {
    return reference.dataset.tooltip || 'По умолчанию';
  },
  interactive: true,
});
  • reference — элемент, для которого создается подсказка.
  • dataset.tooltip — возможность задавать индивидуальное содержимое для каждого динамически созданного элемента.

Инициализация отдельных динамических элементов

Если элементы создаются программно и требуется мгновенная инициализация, можно использовать обычный вызов tippy() после добавления элемента в DOM:

const newButton = document.createElement('button');
newButton.textContent = 'Нажми меня';
newButton.classList.add('dynamic-button');
newButton.dataset.tooltip = 'Я подсказка';
document.body.appendChild(newButton);

tippy(newButton, {
  content: newButton.dataset.tooltip,
  placement: 'right',
});

Этот метод гарантирует, что каждый новый элемент будет иметь собственную подсказку, но при большом количестве элементов проще использовать делегирование.


Управление обновлением контента после динамических изменений

Если содержимое элемента или его атрибуты изменяются после инициализации подсказки, можно использовать метод setContent():

const tip = tippy(newButton, {
  content: 'Первоначальный текст',
});

newButton.addEventListener('click', () => {
  tip.setContent('Обновленный текст');
});

setContent() позволяет динамически обновлять текст подсказки без необходимости пересоздавать объект tippy.


Динамическое удаление и уничтожение

Для элементов, которые удаляются из DOM, важно корректно освобождать ресурсы. Tippy.js предоставляет метод destroy():

const tipInstance = tippy(newButton, { content: 'Подсказка' });

// Позже
tipInstance.destroy();

Если используется делегирование, подсказки автоматически обрабатываются для всех элементов, и ручное уничтожение отдельных экземпляров не требуется. Однако при прямой инициализации каждого элемента destroy() предотвращает утечки памяти.


Оптимизация для больших списков

При работе с динамическими списками, например, генерируемыми из API:

  • Использовать делегирование, чтобы не создавать тысячи отдельных экземпляров Tippy.js.
  • Кэшировать содержимое, если оно повторяется, чтобы избежать лишних вычислений в функции content.
  • Ограничивать интерактивность, когда это не требуется, для повышения производительности.
tippy.delegate(document.body, {
  target: '.list-item',
  content(reference) {
    return reference.getAttribute('data-title') || 'Нет данных';
  },
  interactive: false,
});

Совместимость с фреймворками

  • React / Vue / Angular: динамическое добавление элементов часто связано с рендерингом компонентов. Используется либо прямое создание Tippy через ref или mounted хуки, либо делегирование по селектору, если компоненты часто создаются и удаляются.
  • Shadow DOM: при динамическом добавлении элементов внутри Shadow DOM необходимо инициализировать Tippy внутри соответствующего shadow root.

Практические советы

  • Для динамических элементов, создаваемых массово, делегирование предпочтительнее прямой инициализации, особенно если элементы могут удаляться и создаваться повторно.
  • Использование content как функции позволяет связывать подсказку с атрибутами или данными элемента, что упрощает управление содержимым.
  • Следует учитывать производительность и очищать экземпляры Tippy.js при удалении элементов, если делегирование не используется.

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