onDraw представляет собой callback-функцию, вызываемую каждый раз после построения (отрисовки) календаря в интерфейсе Pikaday. Это один из ключевых механизмов, позволяющих вмешиваться в процесс визуализации и модифицировать DOM-структуру уже после того, как библиотека сформировала HTML календаря.
Основная задача onDraw заключается в пост-обработке отрисованного календаря: добавлении классов, динамической модификации элементов, внедрении кастомного поведения и синхронизации UI с внешним состоянием приложения.
onDraw: function() { }
Функция вызывается без обязательных параметров, однако важным является контекст выполнения:
this внутри onDraw указывает на экземпляр
Pikadaythis.el, this._o, this._current,
this._renderStateПример доступа к текущему месяцу:
onDraw: function() {
console.log(this.getMoment().format('YYYY-MM'));
}
Callback вызывается после следующих событий:
Важно учитывать, что onDraw не вызывается при каждом изменении даты выбора, если оно не сопровождается перестроением интерфейса.
На момент выполнения callback:
Это делает onDraw финальной точкой для модификации визуального слоя перед отображением пользователю.
Одна из самых распространённых задач — динамическая подсветка дат:
var picker = new Pikaday({
field: document.getElementById('date'),
onDraw: function() {
var days = this.el.querySelectorAll('.pika-day');
days.forEach(function(day) {
var date = day.getAttribute('data-pika-day');
if (date === '15') {
day.classList.add('special-day');
}
});
}
});
onDraw: function() {
var days = this.el.querySelectorAll('.pika-day');
days.forEach((day) => {
var dayNum = parseInt(day.textContent, 10);
if (dayNum % 7 === 0 || dayNum % 7 === 6) {
day.classList.add('weekend-highlight');
}
});
}
onDraw: function() {
var disabledDays = [5, 10, 20];
this.el.querySelectorAll('.pika-day').forEach(function(day) {
var value = parseInt(day.textContent, 10);
if (disabledDays.indexOf(value) !== -1) {
day.classList.add('is-disabled');
}
});
}
Экземпляр Pikaday предоставляет доступ к текущему отображаемому месяцу:
this.getDate() — выбранная датаthis.getMoment() — текущая дата через Moment.js (если
используется)this.gotoMonth() — переход к месяцуthis.gotoYear() — переход к годуПример использования текущего состояния:
onDraw: function() {
var currentMonth = this.getMoment().month();
if (currentMonth === 11) {
this.el.classList.add('december-theme');
} else {
this.el.classList.remove('december-theme');
}
}
Поскольку календарь полностью перерисовывается при каждом вызове, любые изменения DOM должны быть:
Пример безопасного паттерна:
onDraw: function() {
var root = this.el;
root.querySelectorAll('.custom-marker').forEach(function(el) {
el.remove();
});
var today = new Date().getDate();
root.querySelectorAll('.pika-day').forEach(function(day) {
if (parseInt(day.textContent, 10) === today) {
var marker = document.createElement('span');
marker.className = 'custom-marker';
day.appendChild(marker);
}
});
}
onOpen вызывается при открытии календаряonDraw вызывается при каждом рендереonDraw может срабатывать многократно после
onOpen.
onSelect реагирует на выбор датыonDraw реагирует на перерисовку интерфейсаВыбор даты может триггерить перерисовку, что косвенно вызывает
onDraw.
Изменение состояния поля ввода может привести к:
onDrawКлючевая особенность onDraw заключается в высокой частоте вызова:
Это накладывает ограничения:
Для снижения нагрузки используются следующие подходы:
onDraw: function() {
if (!this._cachedDays) {
this._cachedDays = this.el.querySelectorAll('.pika-day');
}
this._cachedDays.forEach(function(day) {
day.classList.add('optimized');
});
}
onDraw: function() {
if (this._lastRenderedMonth === this.getMoment().month()) {
return;
}
this._lastRenderedMonth = this.getMoment().month();
}
Использование onDraw тесно связано с CSS-моделью:
Пример структуры классов:
.special-day {
background-color: #ffe08a;
border-radius: 4px;
}
.weekend-highlight {
color: #d33;
}
var events = {
12: 'meeting',
18: 'holiday',
25: 'deadline'
};
onDraw: function() {
this.el.querySelectorAll('.pika-day').forEach((day) => {
var d = parseInt(day.textContent, 10);
if (events[d]) {
day.setAttribute('data-event', events[d]);
day.classList.add('has-event');
}
});
}
onDraw: function() {
var selected = this.getDate();
if (selected) {
document.body.setAttribute('data-selected-date', selected.toISOString());
}
}