Метод destroy() в библиотеке Pikaday предназначен для полного уничтожения экземпляра календаря и освобождения связанных с ним ресурсов. После вызова этого метода объект календаря прекращает свою работу, удаляет созданные обработчики событий, скрывает интерфейс выбора даты и исключает дальнейшее взаимодействие с экземпляром.
Метод используется в ситуациях, когда календарь больше не нужен: при удалении элементов страницы, динамическом обновлении интерфейса, переходе между экранами одностраничных приложений или повторной инициализации компонента.
Сигнатура метода проста:
picker.destroy();
Метод не принимает параметров и не возвращает значения.
При создании объекта Pikaday библиотека выполняет ряд внутренних действий:
Если экземпляр больше не используется, но не уничтожается, в памяти браузера могут оставаться ссылки на объекты и обработчики событий. В небольших проектах это редко становится проблемой, однако в крупных приложениях подобные утечки постепенно накапливаются.
Метод destroy() позволяет корректно завершить жизненный
цикл компонента.
Создание календаря:
const picker = new Pikaday({
field: document.getElementById('date')
});
Уничтожение:
picker.destroy();
После выполнения этого кода календарь перестаёт существовать.
При вызове метода библиотека выполняет несколько операций.
Во время инициализации Pikaday регистрирует множество событий:
input.addEventListener('focus', ...);
document.addEventListener('click', ...);
После вызова destroy() эти обработчики снимаются.
Схематически процесс выглядит так:
picker.destroy();
Результат:
События отключены
↓
Календарь больше не реагирует на действия пользователя
Если календарь был добавлен в DOM, метод удаляет соответствующий элемент.
Например, до уничтожения:
<body>
<input id="date">
<div class="pika-single">
...
</div>
</body>
После уничтожения:
<body>
<input id="date">
</body>
Элемент календаря исчезает из документа.
Pikaday хранит ссылки на:
После уничтожения эти связи становятся неактуальными и могут быть освобождены сборщиком мусора JavaScript.
Частая ситуация — необходимость создать календарь заново с другими настройками.
Неправильный подход:
let picker = new Pikaday({
field: input
});
picker = new Pikaday({
field: input,
firstDay: 1
});
В этом случае старый экземпляр остаётся в памяти.
Правильный вариант:
picker.destroy();
picker = new Pikaday({
field: input,
firstDay: 1
});
Старый объект удаляется корректно, после чего создаётся новый.
В современных SPA-приложениях элементы интерфейса постоянно создаются и удаляются.
Пример жизненного цикла компонента:
function mount() {
picker = new Pikaday({
field: document.getElementById('date')
});
}
function unmount() {
picker.destroy();
}
При закрытии страницы или компонента календарь уничтожается вместе со всеми связанными ресурсами.
Рассмотрим форму, которая создаётся программно.
Создание:
const input = document.createElement('input');
document.body.appendChild(input);
const picker = new Pikaday({
field: input
});
Удаление формы:
picker.destroy();
input.remove();
Такой порядок действий считается безопасным.
Если сначала удалить поле:
input.remove();
а затем забыть уничтожить календарь, часть внутренних ссылок может остаться в памяти до очередной очистки браузером.
В сложных приложениях экземпляр может существовать не всегда.
Распространённая практика:
if (picker) {
picker.destroy();
}
Либо:
picker?.destroy();
Это предотвращает ошибки при обращении к несуществующему объекту.
После уничтожения экземпляр перестаёт быть рабочим объектом.
Например:
picker.destroy();
picker.show();
Такой код является логической ошибкой.
После уничтожения необходимо создать новый экземпляр:
picker.destroy();
picker = new Pikaday({
field: input
});
Только новый объект может снова отображать календарь.
Начинающие разработчики часто путают эти методы.
Скрывает календарь:
picker.hide();
Результат:
picker.show();
Полностью удаляет календарь:
picker.destroy();
Результат:
Некоторые разработчики пытаются удалить календарь самостоятельно.
Например:
document
.querySelector('.pika-single')
.remove();
Внешне календарь исчезнет, однако:
Правильный способ:
picker.destroy();
Метод выполняет весь необходимый набор операций.
Предположим, требуется переключаться между двумя вариантами календаря.
Первый режим:
let picker = new Pikaday({
field: input,
firstDay: 1
});
Переключение:
picker.destroy();
picker = new Pikaday({
field: input,
firstDay: 0
});
Такой подход обеспечивает чистое создание нового экземпляра без накопления лишних объектов.
Если на странице присутствует несколько экземпляров Pikaday:
const startPicker = new Pikaday({
field: startInput
});
const endPicker = new Pikaday({
field: endInput
});
Каждый экземпляр уничтожается отдельно:
startPicker.destroy();
endPicker.destroy();
Уничтожение одного календаря не влияет на другой.
Календарь создаётся при открытии окна:
let picker;
function openModal() {
picker = new Pikaday({
field: document.getElementById('date')
});
}
При закрытии окна:
function closeModal() {
picker.destroy();
}
Если модальное окно открывается много раз, такой подход предотвращает накопление лишних экземпляров.
Проблемный код:
button.addEventListener('click', () => {
new Pikaday({
field: input
});
});
После нескольких нажатий появится множество экземпляров.
Правильный вариант:
if (picker) {
picker.destroy();
}
picker = new Pikaday({
field: input
});
Ошибка:
picker.destroy();
picker.setDate(new Date());
После удаления экземпляр не должен использоваться.
Лучше сразу создать новый объект:
picker.destroy();
picker = new Pikaday({
field: input
});
picker.setDate(new Date());
Нежелательный вариант:
new Pikaday({
field: input
});
Ссылка на объект отсутствует, поэтому позже вызвать
destroy() невозможно.
Предпочтительно сохранять экземпляр:
const picker = new Pikaday({
field: input
});
picker.destroy();
container.remove();
picker.destroy();
picker = new Pikaday(options);
const picker = new Pikaday({
field: input
});
picker.destroy();
После этого экземпляр считается завершившим жизненный цикл и должен быть заменён новым объектом при необходимости дальнейшей работы.
Создание:
const picker = new Pikaday({
field: input
});
Работа:
picker.show();
picker.setDate(new Date());
picker.hide();
Завершение:
picker.destroy();
Цепочка выглядит следующим образом:
Создание экземпляра
↓
Использование календаря
↓
Скрытие и отображение
↓
destroy()
↓
Удаление событий
Удаление DOM-элементов
Освобождение ресурсов
Завершение работы экземпляра
Метод destroy() является завершающим этапом жизненного
цикла объекта Pikaday и обеспечивает корректное освобождение ресурсов,
предотвращение утечек памяти и безопасное удаление календаря из
приложения.