Библиотека Pikaday интегрируется с DOM через привязку к
input-элементу и набор стандартных браузерных событий:
focus, click, keydown,
blur. Поведение по умолчанию формируется комбинацией этих
событий и внутреннего состояния календаря (open/close, selected date,
render cycle). Отмена стандартных действий в этом контексте означает
управление тремя слоями:
Стандартное поведение: при фокусе или клике на поле
input календарь открывается автоматически.
Контроль осуществляется через настройку привязки:
const picker = new Pikaday({
field: document.querySelector('#date'),
bound: false
});
При bound: false библиотека перестаёт автоматически
слушать события поля ввода. Открытие и закрытие полностью переводится в
ручное управление через методы:
picker.show();
picker.hide();
Такой подход полностью устраняет стандартное поведение и заменяет его явным контролем.
Если требуется сохранить привязку, но отменить стандартное открытие, используется перехват DOM-события до обработки Pikaday:
const input = document.querySelector('#date');
input.addEventListener('click', (e) => {
e.preventDefault();
e.stopImmediatePropagation();
});
Ключевые моменты:
preventDefault() блокирует стандартное действие
браузераstopImmediatePropagation() предотвращает выполнение
обработчиков PikadayЭто эффективно подавляет открытие календаря при клике, но сохраняет
возможность программного управления через show().
Pikaday использует focus как один из триггеров открытия.
Для его блокировки применяется аналогичный подход:
input.addEventListener('focus', (e) => {
e.preventDefault();
e.stopPropagation();
}, true);
Использование третьего аргумента true (capture phase)
важно: обработчик срабатывает до внутренних событий библиотеки.
Input с календарём часто находится внутри формы, и стандартное поведение submit может конфликтовать с логикой выбора даты.
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
e.preventDefault();
});
Хотя это не напрямую связано с Pikaday, в большинстве интеграций
выбор даты автоматически триггерит валидацию или submit через
change.
Pikaday обновляет значение input через onSelect. Это
приводит к срабатыванию change события, что может считаться
“действием по умолчанию” в бизнес-логике.
const picker = new Pikaday({
field: document.querySelector('#date'),
onSelect: function() {
const value = this.getDate();
// временное отключение реакции input
const input = this._o.field;
const descriptor = Object.getOwnPropertyDescriptor(
HTMLInputElement.prototype,
'value'
);
descriptor.set.call(input, value);
}
});
Более практичный вариант — временное отключение слушателей:
let suppress = false;
input.addEventListener('change', (e) => {
if (suppress) return;
console.log('обычное изменение');
});
const picker = new Pikaday({
field: input,
onSelect: function() {
suppress = true;
input.value = this.toString();
suppress = false;
}
});
По умолчанию Pikaday записывает дату в поле ввода. Это можно отключить, сохранив только внутреннее состояние календаря:
const picker = new Pikaday({
field: document.querySelector('#date'),
toString(date) {
return '';
},
onSelect: function(date) {
// значение не записывается в input автоматически
}
});
Альтернативный способ — ручное управление:
const picker = new Pikaday({
field: document.querySelector('#date'),
onSelect: function(date) {
// полный контроль над записью
}
});
По умолчанию календарь закрывается при потере фокуса input. Это поведение можно перехватить.
const input = document.querySelector('#date');
input.addEventListener('blur', (e) => {
e.preventDefault();
setTimeout(() => {
input.focus();
}, 0);
});
Такой подход удерживает календарь открытым даже при попытке ухода с поля.
Pikaday закрывается при клике вне области календаря. Это поведение
можно изменить через onClose и внешнюю логику.
const picker = new Pikaday({
field: document.querySelector('#date'),
onClose: function() {
// предотвращение повторного закрытия через show()
setTimeout(() => {
if (this._preventClose) {
this.show();
}
}, 0);
}
});
И переключатель состояния:
picker._preventClose = true;
По умолчанию Pikaday обрабатывает стрелки, Enter и Escape.
input.addEventListener('keydown', (e) => {
const blockedKeys = ['ArrowUp', 'ArrowDown', 'Escape'];
if (blockedKeys.includes(e.key)) {
e.preventDefault();
e.stopPropagation();
}
}, true);
Это предотвращает:
Некоторые реализации Pikaday позволяют переключать месяцы через wheel-события (в зависимости от версии и кастомизации).
const container = document.querySelector('.pika-single');
container.addEventListener('wheel', (e) => {
e.preventDefault();
e.stopPropagation();
}, { passive: false });
Максимальный контроль достигается отключением всех стандартных триггеров и использованием API напрямую:
const picker = new Pikaday({
field: document.querySelector('#date'),
bound: false,
onSelect: function() {
document.querySelector('#date').value = this.toString();
}
});
document.querySelector('#openBtn').addEventListener('click', () => {
picker.show();
});
document.querySelector('#closeBtn').addEventListener('click', () => {
picker.hide();
});
В этом режиме:
Отмена действий в Pikaday часто сводится к управлению порядком выполнения событий:
true)Использование capture-фазы позволяет перехватывать события раньше библиотеки:
input.addEventListener('click', handler, true);
Именно этот механизм обеспечивает стабильное подавление поведения по умолчанию без модификации исходного кода библиотеки.
При изменении даты Pikaday обновляет DOM-значение input. Это может вызывать:
Для изоляции применяется буферизация:
let internalUpdate = false;
const picker = new Pikaday({
field: input,
onSelect: function() {
internalUpdate = true;
input.value = this.toString();
internalUpdate = false;
}
});
input.addEventListener('input', (e) => {
if (internalUpdate) return;
// внешняя логика
});
Этот механизм разделяет внутренние изменения календаря и пользовательский ввод.
Полная отмена стандартных действий достигается отказом от DOM-событий в пользу методов экземпляра:
show()hide()gotoDate()setDate()destroy()picker.setDate(new Date(), true);
picker.hide();
Второй параметр true предотвращает триггер событий,
связанных с изменением.
Контроль над стандартным поведением в Pikaday строится не на одной точке отмены, а на комбинации перехвата событий, отключения привязки, управления фазами обработки и изоляции DOM-синхронизации.