Практическое применение хуков

Tippy.js предоставляет мощный механизм управления жизненным циклом всплывающих подсказок с помощью хуков. Хуки — это функции, которые вызываются в определённые моменты жизненного цикла тултипа: при создании, показе, скрытии или уничтожении. Основные хуки позволяют управлять поведением компонента на самых тонких уровнях.

Базовая структура хуков:

tippy(referenceElement, {
  content: 'Подсказка',
  onShow(instance) {
    console.log('Подсказка показывается', instance);
  },
  onHide(instance) {
    console.log('Подсказка скрывается', instance);
  },
  onMount(instance) {
    console.log('Подсказка смонтирована в DOM', instance);
  },
  onUnmount(instance) {
    console.log('Подсказка удалена из DOM', instance);
  }
});

Каждый из этих хуков принимает объект instance — ссылку на текущий экземпляр Tippy. Через него можно изменять свойства тултипа в реальном времени.


Хук onShow и управление показом

Хук onShow вызывается перед тем, как тултип становится видимым. Он принимает объект instance и позволяет предотвратить показ или динамически менять содержимое.

tippy('#button', {
  content: 'Динамическая подсказка',
  onShow(instance) {
    if (!instance.props.content) {
      instance.setContent('Контент отсутствует');
    }
  }
});

Ключевой момент: возвращение false в onShow предотвращает отображение тултипа.

onShow(instance) {
  if (!instance.props.content) {
    return false; // Тултип не откроется
  }
}

Хук onHide и контроль скрытия

Хук onHide срабатывает перед скрытием тултипа. Его можно использовать для анимации, задержек или логики, основанной на пользовательских условиях.

tippy('#button', {
  content: 'Закрываем с задержкой',
  onHide(instance) {
    console.log('Подсказка готовится к скрытию');
    // Можно вернуть Promise для асинхронной задержки
    return new Promise(resolve => setTimeout(resolve, 500));
  }
});

Особенность: Tippy.js поддерживает асинхронные операции в хуках, что позволяет делать плавные анимации и проверять условия перед закрытием.


Хук onMount и работа с DOM

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

tippy('#button', {
  content: '<strong>Стилизация через JS</strong>',
  allowHTML: true,
  onMount(instance) {
    const tooltipContent = instance.popper.querySelector('.tippy-content');
    tooltipContent.style.backgroundColor = 'lightblue';
  }
});

Применение: динамическое стилизование, интеграция с анимациями, кастомизация классов.


Хук onUnmount и очистка ресурсов

onUnmount вызывается после удаления тултипа из DOM. Этот хук идеален для освобождения ресурсов, удаления обработчиков событий или остановки таймеров.

tippy('#button', {
  content: 'Будет уничтожен',
  onUnmount(instance) {
    console.log('Тултип уничтожен', instance);
  }
});

Комплексное использование хуков

Хуки можно комбинировать для построения сложного поведения. Например, динамическое содержимое с проверкой и анимацией:

tippy('#button', {
  content: 'Начало работы',
  allowHTML: true,
  onShow(instance) {
    instance.setContent('<em>Загрузка данных...</em>');
  },
  onMount(instance) {
    setTimeout(() => {
      instance.setContent('Данные загружены');
    }, 1000);
  },
  onHide(instance) {
    console.log('Подсказка скрыта');
  },
  onUnmount(instance) {
    console.log('Очистка завершена');
  }
});

В этом примере используется полный жизненный цикл тултипа: сначала динамическая загрузка, затем монтаж, скрытие и очистка ресурсов.


Советы по применению хуков

  • Минимизировать синхронную работу в onShow и onHide, чтобы не блокировать отображение.
  • Использовать onMount для любых операций с реальным DOM.
  • Хуки могут быть асинхронными, что позволяет интегрировать запросы данных или анимации.
  • Можно комбинировать хуки с опцией delay для плавного показа/скрытия.
  • Для многоразового поведения создаются функции-хелперы, которые возвращают объекты с нужными хуками.

Примеры продвинутых сценариев

1. Анимация с задержкой перед скрытием:

tippy('#button', {
  content: 'Анимируемое скрытие',
  onHide(instance) {
    return new Promise(resolve => {
      instance.popper.classList.add('fade-out');
      setTimeout(resolve, 300);
    });
  }
});

2. Динамическая подгрузка контента через API:

tippy('#button', {
  content: 'Загрузка...',
  onShow(instance) {
    fetch('/api/tooltip-data')
      .then(res => res.text())
      .then(data => instance.setContent(data));
  }
});

3. Управление событиями внутри тултипа:

tippy('#button', {
  content: '<button class="confirm">Подтвердить</button>',
  allowHTML: true,
  onMount(instance) {
    instance.popper.querySelector('.confirm').addEventListener('click', () => {
      console.log('Действие выполнено');
      instance.hide();
    });
  }
});

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