Асинхронная загрузка содержимого

Tippy.js предоставляет гибкий и мощный механизм для создания всплывающих подсказок, который полностью совместим с асинхронной загрузкой данных. Асинхронный контент позволяет динамически подгружать информацию из внешних источников, таких как API, базы данных или локальные ресурсы, и отображать её в тултипах без перезагрузки страницы.

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

Ключевой момент — это возможность передать в опцию content функцию, которая возвращает Promise. Tippy.js будет ожидать завершения промиса и автоматически обновит содержимое тултипа.

import tippy from 'tippy.js';

tippy('#asyncButton', {
  content: async () => {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return `Загруженные данные: ${data.value}`;
  },
  allowHTML: true,
  interactive: true,
});

В этом примере:

  • content получает асинхронную функцию, возвращающую промис.
  • Tippy.js автоматически рендерит тултип после завершения промиса.
  • Опция allowHTML позволяет безопасно использовать HTML-разметку в подгружаемом контенте.
  • interactive обеспечивает возможность взаимодействия с тултипом (например, клик внутри всплывающей подсказки).

Предзагрузка и индикация состояния

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

const tip = tippy('#asyncButton', {
  content: 'Загрузка...',
  allowHTML: true,
  interactive: true,
});

document.querySelector('#asyncButton').addEventListener('mouseenter', async () => {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  tip[0].setContent(`Данные: ${data.value}`);
});

Особенности данного подхода:

  • Начальное содержимое устанавливается статически (Загрузка...).
  • После завершения асинхронной операции вызывается метод setContent для обновления тултипа.
  • Такой способ полезен для сложных или больших данных, когда время загрузки может превышать 200–300 мс.

Асинхронные тултипы с onShow и onHidden

Для оптимизации нагрузки на сервер или API удобно подгружать данные только при открытии тултипа и очищать их после закрытия.

tippy('#asyncButton', {
  content: 'Загрузка...',
  onShow: async (instance) => {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    instance.setContent(`Динамический контент: ${data.value}`);
  },
  onHidden: (instance) => {
    instance.setContent('Загрузка...');
  },
  allowHTML: true,
});

Принцип работы:

  • onShow выполняется перед отображением тултипа. Можно асинхронно загружать данные.
  • onHidden позволяет сбросить контент к первоначальному состоянию, чтобы при повторном открытии данные заново загружались.
  • Такой подход предотвращает устаревший контент и экономит память.

Асинхронная интеграция с внешними библиотеками

Tippy.js совместим с любыми библиотеками для работы с асинхронными данными, например, Axios или GraphQL-клиентами:

import axios from 'axios';

tippy('#asyncButton', {
  content: async () => {
    const { data } = await axios.get('https://api.example.com/data');
    return `<strong>${data.title}</strong><p>${data.description}</p>`;
  },
  allowHTML: true,
  interactive: true,
});

Особенности использования:

  • axios позволяет более гибко управлять заголовками и обработкой ошибок.
  • HTML-разметка в return позволяет форматировать контент, например, добавлять заголовки и параграфы.
  • interactive: true делает тултип кликабельным и позволяет вставлять внутрь кнопки или ссылки.

Обработка ошибок при асинхронной загрузке

Для устойчивости интерфейса необходимо предусматривать обработку ошибок:

tippy('#asyncButton', {
  content: async () => {
    try {
      const response = await fetch('https://api.example.com/data');
      if (!response.ok) throw new Error('Ошибка сети');
      const data = await response.json();
      return `Контент: ${data.value}`;
    } catch (err) {
      return `Ошибка загрузки: ${err.message}`;
    }
  },
  allowHTML: true,
});

Таким образом:

  • Любая ошибка в промисе корректно отображается пользователю.
  • Tippy.js не ломается при отклонении промиса.
  • Можно выводить локализованные или пользовательские сообщения об ошибках.

Применение в SPA и динамических интерфейсах

В современных одностраничных приложениях (React, Vue, Svelte) Tippy.js с асинхронным контентом позволяет:

  • Подгружать данные только при необходимости.
  • Обновлять тултипы после изменения состояния компонента.
  • Минимизировать избыточные запросы, используя onShow вместо предзагрузки.
tippy(document.querySelectorAll('.dynamic-tooltip'), {
  content: async (reference) => {
    const id = reference.dataset.id;
    const response = await fetch(`https://api.example.com/item/${id}`);
    const data = await response.json();
    return `${data.name} — ${data.description}`;
  },
  allowHTML: true,
});

Ключевые моменты:

  • reference позволяет получать атрибуты элемента и подгружать соответствующие данные.
  • Легко масштабируется на множество элементов с одинаковой логикой загрузки.
  • Динамическая подгрузка уменьшает первоначальный вес страницы и ускоряет рендеринг интерфейса.

Асинхронная загрузка контента в Tippy.js предоставляет полный контроль над процессом рендеринга подсказок, делая их адаптивными, интерактивными и интегрированными с современными веб-технологиями.