Использование data-атрибутов

Библиотека Tippy.js позволяет конфигурировать всплывающие подсказки (tooltips) не только через JavaScript, но и напрямую в HTML с помощью data-* атрибутов. Такой подход упрощает интеграцию, особенно в проектах с большим количеством однотипных элементов, а также в ситуациях, где логика и разметка должны быть максимально связаны.

Механизм основан на автоматическом считывании атрибутов, начинающихся с data-tippy-*, и преобразовании их в соответствующие опции конфигурации.


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

<button data-tippy-content="Подсказка">Наведи курсор</button>

<script>
  tippy('[data-tippy-content]');
</script>
  • Атрибут data-tippy-content задаёт текст подсказки
  • Селектор [data-tippy-content] автоматически находит все элементы с этим атрибутом
  • Конфигурация по умолчанию применяется ко всем найденным элементам

Соответствие data-атрибутов опциям Tippy

Каждая опция Tippy может быть задана через HTML-атрибут. Формат следующий:

data-tippy-<имя-опции>

Примеры:

Опция JS data-атрибут
content data-tippy-content
placement data-tippy-placement
animation data-tippy-animation
theme data-tippy-theme
delay data-tippy-delay
arrow data-tippy-arrow
interactive data-tippy-interactive

Примеры конфигурации через HTML

Позиционирование

<button 
  data-tippy-content="Снизу" 
  data-tippy-placement="bottom">
  Кнопка
</button>

Анимация

<button 
  data-tippy-content="Анимация scale" 
  data-tippy-animation="scale">
  Кнопка
</button>

Тема

<button 
  data-tippy-content="Тёмная тема" 
  data-tippy-theme="dark">
  Кнопка
</button>

Работа с логическими значениями

Булевы значения передаются строками:

<button 
  data-tippy-content="Интерактивный tooltip"
  data-tippy-interactive="true">
  Наведи курсор
</button>

Особенности:

  • "true"true
  • "false"false
  • отсутствие атрибута → значение по умолчанию

Числовые параметры

Некоторые опции принимают числа или массивы чисел:

<button 
  data-tippy-content="Задержка"
  data-tippy-delay="[100, 200]">
  Кнопка
</button>

В данном случае:

  • 100 мс — задержка появления
  • 200 мс — задержка исчезновения

Строка автоматически парсится в массив.


HTML-контент внутри подсказки

<button 
  data-tippy-content="<strong>Жирный текст</strong>"
  data-tippy-allowHTML="true">
  Наведи
</button>

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

  • allowHTML="true" обязателен для рендеринга HTML
  • без него HTML будет экранирован

Глобальная инициализация

Можно инициализировать все подсказки сразу:

tippy('[data-tippy-content]');

Либо комбинировать с дополнительными настройками:

tippy('[data-tippy-content]', {
  animation: 'fade',
  theme: 'light'
});

При этом:

  • значения из data-* имеют приоритет над глобальными настройками
  • глобальные опции выступают как fallback

Переопределение через JavaScript

Если элемент уже содержит data-*, их можно переопределить:

<button 
  id="btn"
  data-tippy-content="HTML значение">
  Кнопка
</button>
tippy('#btn', {
  content: 'JS значение'
});

Результат:

  • используется JS значение, а не HTML-атрибут

Использование кастомных data-атрибутов

Возможна интеграция с собственными атрибутами:

<button data-tooltip="Своя подсказка">Кнопка</button>
tippy('[data-tooltip]', {
  content(reference) {
    return reference.getAttribute('data-tooltip');
  }
});

Преимущества:

  • гибкость
  • возможность внедрения в существующую разметку

Массовое применение в списках

<ul>
  <li data-tippy-content="Элемент 1">1</li>
  <li data-tippy-content="Элемент 2">2</li>
  <li data-tippy-content="Элемент 3">3</li>
</ul>
tippy('li');

Подход позволяет:

  • избежать написания JS для каждого элемента
  • централизовать поведение

Динамическое изменение атрибутов

const btn = document.querySelector('button');

btn.setAttribute('data-tippy-content', 'Новое значение');

Однако:

  • уже инициализированный tooltip не обновится автоматически

Для обновления:

const instance = tippy(btn);
instance.setContent('Новое значение');

Ограничения и особенности

1. Типизация данных

Все значения приходят как строки, и Tippy выполняет попытку преобразования:

  • "true" → boolean
  • "123" → number
  • "[1,2]" → array

Ошибки в формате приводят к некорректной работе.


2. Сложные объекты

Нельзя передавать функции через HTML:

<!-- НЕ РАБОТАЕТ -->
data-tippy-onShow="function() { ... }"

Для таких случаев используется только JavaScript.


3. Производительность

При большом количестве элементов:

  • чтение атрибутов дешевле, чем генерация конфигурации вручную
  • но массовая инициализация может требовать оптимизации (например, делегирование)

Комбинированный подход

Часто используется сочетание:

  • базовые параметры через data-*
  • сложная логика через JS
<button 
  class="tooltip"
  data-tippy-content="Текст"
  data-tippy-theme="light">
  Кнопка
</button>
tippy('.tooltip', {
  onShow(instance) {
    console.log('Показ:', instance.reference);
  }
});

Рекомендации по использованию

Использование data-атрибутов оправдано, если:

  • требуется простая конфигурация
  • много однотипных элементов
  • важна читаемость HTML

Использование JavaScript предпочтительно, если:

  • есть динамика
  • требуется логика
  • используются функции и события

Структурирование атрибутов

Для читаемости рекомендуется:

<button
  data-tippy-content="Информация"
  data-tippy-placement="right"
  data-tippy-theme="dark"
  data-tippy-delay="[100, 0]"
>
  Кнопка
</button>

Интеграция с фреймворками

В рамках React, Vue или Angular:

  • data-* удобно использовать в шаблонах
  • инициализация происходит после монтирования компонентов

Пример (условный):

useEffect(() => {
  tippy('[data-tippy-content]');
}, []);

Отладка

При проблемах:

  • проверяется наличие атрибута
  • проверяется корректность значений
  • проверяется инициализация tippy()

Полезно выводить:

console.log(element.dataset);

Расширенные возможности

Можно комбинировать с CSS:

[data-tippy-theme='custom'] {
  color: red;
}

И HTML:

<button 
  data-tippy-content="Кастом"
  data-tippy-theme="custom">
  Кнопка
</button>

Взаимодействие с делегированием

tippy(document.body, {
  target: '[data-tippy-content]'
});

Преимущества:

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

Итоговая структура применения

  1. HTML описывает поведение через data-*
  2. JavaScript выполняет единственную инициализацию
  3. При необходимости логика расширяется через JS API

Такой подход делает код:

  • компактным
  • декларативным
  • масштабируемым