Экземпляры всплывающих подсказок в Tippy.js создаются динамически и привязываются к DOM-элементам. Управление их жизненным циклом — важная часть работы с библиотекой, особенно в сложных интерфейсах, где элементы часто создаются и удаляются.
Каждый вызов tippy() возвращает экземпляр (или массив
экземпляров), который предоставляет методы для управления состоянием
подсказки, включая удаление.
Основной метод удаления:
instance.destroy();
Этот метод полностью уничтожает экземпляр подсказки, включая:
После вызова destroy() экземпляр становится невалидным и
не может быть использован повторно.
Метод destroy() выполняет несколько этапов:
Удаление tooltip-элемента из DOM
Отключение событий
Очистка ссылок
._tippy у целевого элемента удаляетсяСброс состояния
show,
hide и т.д.)Каждый DOM-элемент, к которому привязан Tippy, получает свойство
_tippy, содержащее экземпляр:
const button = document.querySelector('#btn');
button._tippy.destroy();
Это удобно, если прямой доступ к переменной экземпляра отсутствует.
Если tippy() был вызван с селектором, возвращается
массив экземпляров:
const instances = tippy('.item');
instances.forEach(instance => {
instance.destroy();
});
Это стандартный способ очистки группы подсказок.
В приложениях с частыми изменениями DOM (например, SPA) необходимо вручную уничтожать экземпляры перед удалением элементов:
function removeElement(el) {
if (el._tippy) {
el._tippy.destroy();
}
el.remove();
}
Игнорирование этого приводит к:
Важно различать:
| Метод | Описание |
|---|---|
hide() |
Скрывает подсказку, но сохраняет экземпляр |
destroy() |
Полностью удаляет экземпляр |
Пример:
instance.hide(); // подсказка скрыта, но может быть снова показана
instance.destroy(); // экземпляр уничтожен навсегда
После вызова destroy() можно создать новый
экземпляр:
instance.destroy();
const newInstance = tippy(element, {
content: 'Новая подсказка'
});
Это полезно при изменении конфигурации, которую нельзя обновить через
setProps().
При использовании делегирования (tippy.delegate)
создаётся родительский экземпляр:
const delegateInstance = tippy.delegate('.container', {
target: '.child',
content: 'Подсказка'
});
Удаление:
delegateInstance.destroy();
Это удаляет:
Tippy не отслеживает автоматически удаление DOM-элементов, поэтому:
element.remove(); // НЕ уничтожает tippy
Правильный подход:
if (element._tippy) {
element._tippy.destroy();
}
element.remove();
В useEffect:
useEffect(() => {
const instance = tippy(ref.current, { content: '...' });
return () => {
instance.destroy();
};
}, []);
В хуке beforeUnmount:
beforeUnmount() {
if (this.$el._tippy) {
this.$el._tippy.destroy();
}
}
Перед удалением важно убедиться, что экземпляр существует:
if (element._tippy) {
element._tippy.destroy();
}
Иначе возможна ошибка доступа к undefined.
Правильное использование destroy() напрямую влияет
на:
Особенно важно в:
В некоторых случаях вместо полного удаления используются:
instance.disable();
instance.enable();
Это полезно для временного отключения без повторной инициализации.
Если требуется удалить только DOM-элемент подсказки:
instance.popper.remove();
Но это не рекомендуется, так как:
show()Корректный способ — всегда использовать destroy().
1. Удаление элемента без destroy():
element.remove(); // ошибка
2. Повторный вызов destroy():
instance.destroy();
instance.destroy(); // может вызвать ошибку
3. Потеря ссылки на экземпляр:
tippy('.btn'); // без сохранения
// позже нет доступа к destroy()
element._tippydestroy() вместо ручного удаления
элементовdisable(), а не
destroy()Если требуется изменить настройки:
instance.setProps({
content: 'Новое содержимое'
});
Но если меняется фундаментальное поведение (например, стратегия позиционирования), предпочтительнее:
instance.destroy();
tippy(element, newOptions);
После уничтожения:
instance.state.isDestroyed === trueПроверка:
if (!instance.state.isDestroyed) {
instance.destroy();
}
destroy() — основной инструмент очистки